diff options
Diffstat (limited to 'vendor/rustix/src')
157 files changed, 5985 insertions, 4042 deletions
diff --git a/vendor/rustix/src/backend/libc/c.rs b/vendor/rustix/src/backend/libc/c.rs index eb89fa43a..f788cb120 100644 --- a/vendor/rustix/src/backend/libc/c.rs +++ b/vendor/rustix/src/backend/libc/c.rs @@ -86,6 +86,11 @@ pub(crate) const XCASE: tcflag_t = linux_raw_sys::general::XCASE as _; #[cfg(target_os = "aix")] pub(crate) const MSG_DONTWAIT: c_int = libc::MSG_NONBLOCK; +// TODO: Remove once https://github.com/rust-lang/libc/pull/3377 is merged and released. +#[cfg(target_os = "netbsd")] +#[cfg(feature = "net")] +pub(crate) const SO_NOSIGPIPE: c_int = 0x0800; + // 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 @@ -109,7 +114,12 @@ 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"))] +#[cfg(any( + linux_kernel, + target_os = "aix", + target_os = "hurd", + 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}; @@ -123,7 +133,7 @@ pub(super) use libc::{ rlimit64 as rlimit, setrlimit64 as setrlimit, statfs64 as statfs, statvfs64 as statvfs, RLIM_INFINITY, }; -#[cfg(linux_like)] +#[cfg(any(linux_like, target_os = "hurd"))] 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, @@ -144,11 +154,16 @@ pub(super) use libc::{ target_arch = "mips64r6" ) )))] -#[cfg(any(linux_like, target_os = "aix"))] +#[cfg(any(linux_like, target_os = "aix", target_os = "hurd"))] pub(super) use libc::{lstat64 as lstat, stat64 as stat}; -#[cfg(any(linux_kernel, target_os = "aix", target_os = "emscripten"))] +#[cfg(any( + linux_kernel, + target_os = "aix", + target_os = "hurd", + target_os = "emscripten" +))] pub(super) use libc::{pread64 as pread, pwrite64 as pwrite}; -#[cfg(any(target_os = "linux", target_os = "emscripten"))] +#[cfg(any(target_os = "linux", target_os = "hurd", target_os = "emscripten"))] pub(super) use libc::{preadv64 as preadv, pwritev64 as pwritev}; #[cfg(all(target_os = "linux", target_env = "gnu"))] @@ -209,25 +224,6 @@ pub(super) unsafe fn prlimit( 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::*; @@ -248,31 +244,18 @@ mod readwrite_pv64 { 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) + // Unlike the plain "p" functions, the "pv" functions pass their + // offset in an endian-independent way, and always in two registers. + syscall! { + fn preadv( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset_lo: usize, + offset_hi: usize + ) via SYS_preadv -> libc::ssize_t } + preadv(fd, iov, iovcnt, offset as usize, (offset >> 32) as usize) } } pub(in super::super) unsafe fn pwritev64( @@ -288,38 +271,25 @@ mod readwrite_pv64 { 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) + // Unlike the plain "p" functions, the "pv" functions pass their + // offset in an endian-independent way, and always in two registers. + syscall! { + fn pwritev( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset_lo: usize, + offset_hi: usize + ) via SYS_pwritev -> libc::ssize_t } + pwritev(fd, iov, iovcnt, offset as usize, (offset >> 32) as usize) } } } #[cfg(target_os = "android")] pub(super) use readwrite_pv64::{preadv64 as preadv, pwritev64 as pwritev}; -// macOS added preadv and pwritev in version 11.0 +// macOS added `preadv` and `pwritev` in version 11.0. #[cfg(apple)] mod readwrite_pv { weakcall! { @@ -363,33 +333,26 @@ mod readwrite_pv64v2 { 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) + // Unlike the plain "p" functions, the "pv" functions pass their + // offset in an endian-independent way, and always in two registers. + syscall! { + fn preadv2( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset_lo: usize, + offset_hi: usize, + flags: libc::c_int + ) via SYS_preadv2 -> libc::ssize_t } + preadv2( + fd, + iov, + iovcnt, + offset as usize, + (offset >> 32) as usize, + flags, + ) } } pub(in super::super) unsafe fn pwritev64v2( @@ -406,33 +369,26 @@ mod readwrite_pv64v2 { 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) + // Unlike the plain "p" functions, the "pv" functions pass their + // offset in an endian-independent way, and always in two registers. + syscall! { + fn pwritev2( + fd: libc::c_int, + iov: *const libc::iovec, + iovec: libc::c_int, + offset_lo: usize, + offset_hi: usize, + flags: libc::c_int + ) via SYS_pwritev2 -> libc::ssize_t } + pwritev2( + fd, + iov, + iovcnt, + offset as usize, + (offset >> 32) as usize, + flags, + ) } } } @@ -455,33 +411,26 @@ mod readwrite_pv64v2 { 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) + // Unlike the plain "p" functions, the "pv" functions pass their offset + // in an endian-independent way, and always in two registers. + syscall! { + fn preadv2( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset_lo: usize, + offset_hi: usize, + flags: libc::c_int + ) via SYS_preadv2 -> libc::ssize_t } + preadv2( + fd, + iov, + iovcnt, + offset as usize, + (offset >> 32) as usize, + flags, + ) } pub(in super::super) unsafe fn pwritev64v2( fd: libc::c_int, @@ -490,33 +439,26 @@ mod readwrite_pv64v2 { 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) + // Unlike the plain "p" functions, the "pv" functions pass their offset + // in an endian-independent way, and always in two registers. + syscall! { + fn pwritev2( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset_lo: usize, + offset_hi: usize, + flags: libc::c_int + ) via SYS_pwritev2 -> libc::ssize_t } + pwritev2( + fd, + iov, + iovcnt, + offset as usize, + (offset >> 32) as usize, + flags, + ) } } #[cfg(any( diff --git a/vendor/rustix/src/backend/libc/conv.rs b/vendor/rustix/src/backend/libc/conv.rs index 19bf0a7db..253951002 100644 --- a/vendor/rustix/src/backend/libc/conv.rs +++ b/vendor/rustix/src/backend/libc/conv.rs @@ -16,7 +16,7 @@ pub(super) fn c_str(c: &CStr) -> *const c::c_char { c.as_ptr() } -#[cfg(not(any(windows, target_os = "espidf", target_os = "wasi")))] +#[cfg(not(any(windows, target_os = "espidf", target_os = "vita", target_os = "wasi")))] #[inline] pub(super) fn no_fd() -> LibcFd { -1 @@ -192,7 +192,13 @@ pub(super) fn msg_iov_len(len: usize) -> c::size_t { /// Convert the value to the `msg_iovlen` field of a `msghdr` struct. #[cfg(all( - not(any(windows, target_os = "espidf", target_os = "redox", target_os = "wasi")), + not(any( + windows, + target_os = "espidf", + target_os = "redox", + target_os = "vita", + target_os = "wasi" + )), not(any( target_os = "android", all(target_os = "linux", not(target_env = "musl")) @@ -232,6 +238,7 @@ pub(crate) fn msg_control_len(len: usize) -> c::socklen_t { target_os = "haiku", target_os = "nto", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] #[inline] diff --git a/vendor/rustix/src/backend/libc/event/epoll.rs b/vendor/rustix/src/backend/libc/event/epoll.rs index a6087a167..b41b05711 100644 --- a/vendor/rustix/src/backend/libc/event/epoll.rs +++ b/vendor/rustix/src/backend/libc/event/epoll.rs @@ -1,8 +1,4 @@ -//! epoll support. -//! -//! This is an experiment, and it isn't yet clear whether epoll is the right -//! level of abstraction at which to introduce safety. But it works fairly well -//! in simple examples 🙂. +//! Linux `epoll` support. //! //! # Examples //! @@ -74,10 +70,13 @@ //! ``` use crate::backend::c; -use crate::backend::conv::{ret, ret_owned_fd, ret_u32}; +#[cfg(feature = "alloc")] +use crate::backend::conv::ret_u32; +use crate::backend::conv::{ret, ret_owned_fd}; use crate::fd::{AsFd, AsRawFd, OwnedFd}; use crate::io; use crate::utils::as_mut_ptr; +#[cfg(feature = "alloc")] use alloc::vec::Vec; use bitflags::bitflags; use core::ffi::c_void; @@ -93,7 +92,7 @@ bitflags! { /// `EPOLL_CLOEXEC` const CLOEXEC = bitcast!(c::EPOLL_CLOEXEC); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -149,7 +148,7 @@ bitflags! { #[cfg(not(target_os = "android"))] const EXCLUSIVE = bitcast!(c::EPOLLEXCLUSIVE); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -257,6 +256,8 @@ pub fn delete(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. +#[cfg(feature = "alloc")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] 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. @@ -312,8 +313,8 @@ pub struct Event { pub data: EventData, } -/// Data assocated with an [`Event`]. This can either be a 64-bit integer value -/// or a pointer which preserves pointer provenance. +/// Data associated 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 { @@ -395,10 +396,12 @@ struct SixtyFourBitPointer { } /// A vector of `Event`s, plus context for interpreting them. +#[cfg(feature = "alloc")] pub struct EventVec { events: Vec<Event>, } +#[cfg(feature = "alloc")] impl EventVec { /// Constructs an `EventVec` from raw pointer, length, and capacity. /// @@ -473,6 +476,7 @@ impl EventVec { } } +#[cfg(feature = "alloc")] impl<'a> IntoIterator for &'a EventVec { type IntoIter = Iter<'a>; type Item = Event; diff --git a/vendor/rustix/src/backend/libc/event/mod.rs b/vendor/rustix/src/backend/libc/event/mod.rs index 44e8a090a..6aed4612a 100644 --- a/vendor/rustix/src/backend/libc/event/mod.rs +++ b/vendor/rustix/src/backend/libc/event/mod.rs @@ -5,5 +5,5 @@ pub(crate) mod types; #[cfg_attr(windows, path = "windows_syscalls.rs")] pub(crate) mod syscalls; -#[cfg(all(feature = "alloc", linux_kernel))] +#[cfg(linux_kernel)] pub mod epoll; diff --git a/vendor/rustix/src/backend/libc/event/poll_fd.rs b/vendor/rustix/src/backend/libc/event/poll_fd.rs index 3f795d5aa..42f94f3c7 100644 --- a/vendor/rustix/src/backend/libc/event/poll_fd.rs +++ b/vendor/rustix/src/backend/libc/event/poll_fd.rs @@ -48,7 +48,7 @@ bitflags! { )] const RDHUP = c::POLLRDHUP; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/libc/event/types.rs b/vendor/rustix/src/backend/libc/event/types.rs index af052a434..ea4776667 100644 --- a/vendor/rustix/src/backend/libc/event/types.rs +++ b/vendor/rustix/src/backend/libc/event/types.rs @@ -31,7 +31,7 @@ bitflags! { #[cfg(not(target_os = "espidf"))] const SEMAPHORE = bitcast!(c::EFD_SEMAPHORE); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/libc/fs/dir.rs b/vendor/rustix/src/backend/libc/fs/dir.rs index 6cfeb242b..0df1ea1b5 100644 --- a/vendor/rustix/src/backend/libc/fs/dir.rs +++ b/vendor/rustix/src/backend/libc/fs/dir.rs @@ -1,37 +1,51 @@ -#[cfg(not(any(solarish, target_os = "haiku", target_os = "nto")))] +#[cfg(not(any(solarish, target_os = "haiku", target_os = "nto", target_os = "vita")))] use super::types::FileType; use crate::backend::c; use crate::backend::conv::owned_fd; use crate::fd::{AsFd, BorrowedFd}; use crate::ffi::{CStr, CString}; -use crate::fs::{fcntl_getfl, fstat, openat, Mode, OFlags, Stat}; +use crate::fs::{fcntl_getfl, openat, Mode, OFlags}; +#[cfg(not(target_os = "vita"))] +use crate::fs::{fstat, Stat}; #[cfg(not(any( solarish, target_os = "haiku", target_os = "netbsd", target_os = "nto", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] use crate::fs::{fstatfs, StatFs}; -#[cfg(not(any(solarish, target_os = "haiku", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any( + solarish, + target_os = "haiku", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] use crate::fs::{fstatvfs, StatVfs}; use crate::io; -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] +#[cfg(not(any(target_os = "fuchsia", target_os = "vita", target_os = "wasi")))] #[cfg(feature = "process")] use crate::process::fchdir; use alloc::borrow::ToOwned; -#[cfg(not(linux_like))] +#[cfg(not(any(linux_like, target_os = "hurd")))] use c::readdir as libc_readdir; -#[cfg(linux_like)] +#[cfg(any(linux_like, target_os = "hurd"))] use c::readdir64 as libc_readdir; use core::fmt; use core::ptr::NonNull; use libc_errno::{errno, set_errno, Errno}; /// `DIR*` -#[repr(transparent)] -pub struct Dir(NonNull<c::DIR>); +pub struct Dir { + /// The `libc` `DIR` pointer. + libc_dir: NonNull<c::DIR>, + + /// Have we seen any errors in this iteration? + any_errors: bool, +} impl Dir { /// Construct a `Dir` that reads entries from the given directory @@ -42,21 +56,38 @@ impl Dir { } #[inline] + #[allow(unused_mut)] fn _read_from(fd: BorrowedFd<'_>) -> io::Result<Self> { + let mut any_errors = false; + // Given an arbitrary `OwnedFd`, it's impossible to know whether the // user holds a `dup`'d copy which could continue to modify the // file description state, which would cause Undefined Behavior after // our call to `fdopendir`. To prevent this, we obtain an independent // `OwnedFd`. let flags = fcntl_getfl(fd)?; - let fd_for_dir = openat(fd, cstr!("."), flags | OFlags::CLOEXEC, Mode::empty())?; + let fd_for_dir = match openat(fd, cstr!("."), flags | OFlags::CLOEXEC, Mode::empty()) { + Ok(fd) => fd, + #[cfg(not(target_os = "wasi"))] + Err(io::Errno::NOENT) => { + // If "." doesn't exist, it means the directory was removed. + // We treat that as iterating through a directory with no + // entries. + any_errors = true; + crate::io::dup(fd)? + } + Err(err) => return Err(err), + }; let raw = owned_fd(fd_for_dir); unsafe { let libc_dir = c::fdopendir(raw); if let Some(libc_dir) = NonNull::new(libc_dir) { - Ok(Self(libc_dir)) + Ok(Self { + libc_dir, + any_errors, + }) } else { let err = io::Errno::last_os_error(); let _ = c::close(raw); @@ -68,13 +99,19 @@ impl Dir { /// `rewinddir(self)` #[inline] pub fn rewind(&mut self) { - unsafe { c::rewinddir(self.0.as_ptr()) } + self.any_errors = false; + unsafe { c::rewinddir(self.libc_dir.as_ptr()) } } /// `readdir(self)`, where `None` means the end of the directory. pub fn read(&mut self) -> Option<io::Result<DirEntry>> { + // If we've seen errors, don't continue to try to read anyting further. + if self.any_errors { + return None; + } + set_errno(Errno(0)); - let dirent_ptr = unsafe { libc_readdir(self.0.as_ptr()) }; + let dirent_ptr = unsafe { libc_readdir(self.libc_dir.as_ptr()) }; if dirent_ptr.is_null() { let curr_errno = errno().0; if curr_errno == 0 { @@ -82,6 +119,7 @@ impl Dir { None } else { // `errno` is unknown or non-zero, so an error occurred. + self.any_errors = true; Some(Err(io::Errno(curr_errno))) } } else { @@ -99,11 +137,12 @@ impl Dir { solarish, target_os = "aix", target_os = "haiku", - target_os = "nto" + target_os = "nto", + target_os = "vita" )))] d_type: dirent.d_type, - #[cfg(not(any(freebsdlike, netbsdlike)))] + #[cfg(not(any(freebsdlike, netbsdlike, target_os = "vita")))] d_ino: dirent.d_ino, #[cfg(any(freebsdlike, netbsdlike))] @@ -118,9 +157,10 @@ impl Dir { } /// `fstat(self)` + #[cfg(not(target_os = "vita"))] #[inline] pub fn stat(&self) -> io::Result<Stat> { - fstat(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.0.as_ptr())) }) + fstat(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.libc_dir.as_ptr())) }) } /// `fstatfs(self)` @@ -130,27 +170,34 @@ impl Dir { target_os = "netbsd", target_os = "nto", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] #[inline] pub fn statfs(&self) -> io::Result<StatFs> { - fstatfs(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.0.as_ptr())) }) + fstatfs(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.libc_dir.as_ptr())) }) } /// `fstatvfs(self)` - #[cfg(not(any(solarish, target_os = "haiku", target_os = "redox", target_os = "wasi")))] + #[cfg(not(any( + solarish, + target_os = "haiku", + target_os = "redox", + target_os = "vita", + target_os = "wasi" + )))] #[inline] pub fn statvfs(&self) -> io::Result<StatVfs> { - fstatvfs(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.0.as_ptr())) }) + fstatvfs(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.libc_dir.as_ptr())) }) } /// `fchdir(self)` #[cfg(feature = "process")] - #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] + #[cfg(not(any(target_os = "fuchsia", target_os = "vita", 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())) }) + fchdir(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.libc_dir.as_ptr())) }) } } @@ -163,7 +210,7 @@ unsafe impl Send for Dir {} impl Drop for Dir { #[inline] fn drop(&mut self) { - unsafe { c::closedir(self.0.as_ptr()) }; + unsafe { c::closedir(self.libc_dir.as_ptr()) }; } } @@ -178,19 +225,26 @@ impl Iterator for Dir { impl fmt::Debug for Dir { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Dir") - .field("fd", unsafe { &c::dirfd(self.0.as_ptr()) }) - .finish() + let mut s = f.debug_struct("Dir"); + #[cfg(not(target_os = "vita"))] + s.field("fd", unsafe { &c::dirfd(self.libc_dir.as_ptr()) }); + s.finish() } } /// `struct dirent` #[derive(Debug)] pub struct DirEntry { - #[cfg(not(any(solarish, target_os = "aix", target_os = "haiku", target_os = "nto")))] + #[cfg(not(any( + solarish, + target_os = "aix", + target_os = "haiku", + target_os = "nto", + target_os = "vita" + )))] d_type: u8, - #[cfg(not(any(freebsdlike, netbsdlike)))] + #[cfg(not(any(freebsdlike, netbsdlike, target_os = "vita")))] d_ino: c::ino_t, #[cfg(any(freebsdlike, netbsdlike))] @@ -207,14 +261,20 @@ impl DirEntry { } /// Returns the type of this directory entry. - #[cfg(not(any(solarish, target_os = "aix", target_os = "haiku", target_os = "nto")))] + #[cfg(not(any( + solarish, + target_os = "aix", + target_os = "haiku", + target_os = "nto", + target_os = "vita" + )))] #[inline] pub fn file_type(&self) -> FileType { FileType::from_dirent_d_type(self.d_type) } /// Return the inode number of this directory entry. - #[cfg(not(any(freebsdlike, netbsdlike)))] + #[cfg(not(any(freebsdlike, netbsdlike, target_os = "vita")))] #[inline] pub fn ino(&self) -> u64 { self.d_ino as u64 @@ -293,3 +353,45 @@ fn check_dirent_layout(dirent: &c::dirent) { } ); } + +#[test] +fn dir_iterator_handles_io_errors() { + // create a dir, keep the FD, then delete the dir + let tmp = tempfile::tempdir().unwrap(); + let fd = crate::fs::openat( + crate::fs::CWD, + tmp.path(), + crate::fs::OFlags::RDONLY | crate::fs::OFlags::CLOEXEC, + crate::fs::Mode::empty(), + ) + .unwrap(); + + let file_fd = crate::fs::openat( + &fd, + tmp.path().join("test.txt"), + crate::fs::OFlags::WRONLY | crate::fs::OFlags::CREATE, + crate::fs::Mode::RWXU, + ) + .unwrap(); + + let mut dir = Dir::read_from(&fd).unwrap(); + + // Reach inside the `Dir` and replace its directory with a file, which + // will cause the subsequent `readdir` to fail. + unsafe { + let raw_fd = c::dirfd(dir.libc_dir.as_ptr()); + let mut owned_fd: crate::fd::OwnedFd = crate::fd::FromRawFd::from_raw_fd(raw_fd); + crate::io::dup2(&file_fd, &mut owned_fd).unwrap(); + core::mem::forget(owned_fd); + } + + // FreeBSD and macOS seem to read some directory entries before we call + // `.next()`. + #[cfg(any(apple, freebsdlike))] + { + dir.rewind(); + } + + assert!(matches!(dir.next(), Some(Err(_)))); + assert!(matches!(dir.next(), None)); +} diff --git a/vendor/rustix/src/backend/libc/fs/inotify.rs b/vendor/rustix/src/backend/libc/fs/inotify.rs index fea2fad06..2044bd945 100644 --- a/vendor/rustix/src/backend/libc/fs/inotify.rs +++ b/vendor/rustix/src/backend/libc/fs/inotify.rs @@ -18,7 +18,7 @@ bitflags! { /// `IN_NONBLOCK` const NONBLOCK = bitcast!(c::IN_NONBLOCK); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -38,7 +38,7 @@ bitflags! { const CLOSE_NOWRITE = c::IN_CLOSE_NOWRITE; /// `IN_CLOSE_WRITE` const CLOSE_WRITE = c::IN_CLOSE_WRITE; - /// `IN_CREATE ` + /// `IN_CREATE` const CREATE = c::IN_CREATE; /// `IN_DELETE` const DELETE = c::IN_DELETE; @@ -75,7 +75,7 @@ bitflags! { /// `IN_ONLYDIR` const ONLYDIR = c::IN_ONLYDIR; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -90,23 +90,22 @@ pub fn inotify_init(flags: CreateFlags) -> io::Result<OwnedFd> { unsafe { ret_owned_fd(c::inotify_init1(bitflags_bits!(flags))) } } -/// `inotify_add_watch(self, path, flags)`—Adds a watch to inotify +/// `inotify_add_watch(self, path, flags)`—Adds a watch to inotify. /// -/// This registers or updates a watch for the filesystem path `path` -/// and returns a watch descriptor corresponding to this watch. +/// This registers or updates a watch for the filesystem path `path` and +/// returns a watch descriptor corresponding to this watch. /// -/// Note: Due to the existence of hardlinks, providing two -/// different paths to this method may result in it returning -/// the same watch descriptor. An application should keep track of this -/// externally to avoid logic errors. +/// Note: Due to the existence of hardlinks, providing two different paths to +/// this method may result in it returning the same watch descriptor. An +/// application should keep track of this externally to avoid logic errors. pub fn inotify_add_watch<P: crate::path::Arg>( inot: BorrowedFd<'_>, path: P, flags: WatchFlags, ) -> io::Result<i32> { path.into_with_c_str(|path| { - // SAFETY: The fd and path we are passing is guaranteed valid by the type - // system. + // SAFETY: The fd and path we are passing is guaranteed valid by the + // type system. unsafe { ret_c_int(c::inotify_add_watch( borrowed_fd(inot), @@ -117,7 +116,7 @@ pub fn inotify_add_watch<P: crate::path::Arg>( }) } -/// `inotify_rm_watch(self, wd)`—Removes a watch from this inotify +/// `inotify_rm_watch(self, wd)`—Removes a watch from this inotify. /// /// The watch descriptor provided should have previously been returned by /// [`inotify_add_watch`] and not previously have been removed. diff --git a/vendor/rustix/src/backend/libc/fs/mod.rs b/vendor/rustix/src/backend/libc/fs/mod.rs index 9a0b1d3e5..c17e8636f 100644 --- a/vendor/rustix/src/backend/libc/fs/mod.rs +++ b/vendor/rustix/src/backend/libc/fs/mod.rs @@ -6,6 +6,7 @@ pub mod inotify; target_os = "espidf", target_os = "haiku", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] pub(crate) mod makedev; diff --git a/vendor/rustix/src/backend/libc/fs/syscalls.rs b/vendor/rustix/src/backend/libc/fs/syscalls.rs index 5df25daa9..5e0b62f8e 100644 --- a/vendor/rustix/src/backend/libc/fs/syscalls.rs +++ b/vendor/rustix/src/backend/libc/fs/syscalls.rs @@ -1,13 +1,20 @@ //! libc syscalls supporting `rustix::fs`. use crate::backend::c; -#[cfg(any(apple, linux_kernel, feature = "alloc"))] +#[cfg(any( + apple, + linux_kernel, + feature = "alloc", + all(linux_kernel, feature = "procfs") +))] use crate::backend::conv::ret_usize; use crate::backend::conv::{borrowed_fd, c_str, ret, ret_c_int, ret_off_t, ret_owned_fd}; use crate::fd::{BorrowedFd, OwnedFd}; use crate::ffi::CStr; #[cfg(apple)] use crate::ffi::CString; +#[cfg(not(any(target_os = "espidf", target_os = "vita")))] +use crate::fs::Access; #[cfg(not(any( apple, netbsdlike, @@ -16,6 +23,7 @@ use crate::ffi::CString; target_os = "espidf", target_os = "haiku", target_os = "redox", + target_os = "vita", )))] use crate::fs::Advice; #[cfg(not(any(target_os = "espidf", target_os = "redox")))] @@ -28,9 +36,10 @@ use crate::fs::AtFlags; target_os = "espidf", target_os = "nto", target_os = "redox", + target_os = "vita", )))] use crate::fs::FallocateFlags; -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] +#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] use crate::fs::FlockOperation; #[cfg(any(linux_kernel, target_os = "freebsd"))] use crate::fs::MemfdFlags; @@ -43,12 +52,19 @@ use crate::fs::SealFlags; target_os = "netbsd", target_os = "nto", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] use crate::fs::StatFs; -#[cfg(not(target_os = "espidf"))] -use crate::fs::{Access, Timestamps}; -#[cfg(not(any(apple, target_os = "espidf", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any(target_os = "espidf", target_os = "vita")))] +use crate::fs::Timestamps; +#[cfg(not(any( + apple, + target_os = "espidf", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] use crate::fs::{Dev, FileType}; use crate::fs::{Mode, OFlags, SeekFrom, Stat}; #[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] @@ -125,7 +141,7 @@ fn open_via_syscall(path: &CStr, oflags: OFlags, mode: Mode) -> io::Result<Owned 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"))] + #[cfg(all(unix, target_env = "gnu", not(target_os = "hurd")))] if oflags.contains(OFlags::TMPFILE) && crate::backend::if_glibc_is_less_than_2_25() { return open_via_syscall(path, oflags, mode); } @@ -153,7 +169,7 @@ pub(crate) fn open(path: &CStr, oflags: OFlags, mode: Mode) -> io::Result<OwnedF /// Use a direct syscall (via libc) for `openat`. /// /// This is only currently necessary as a workaround for old glibc; see below. -#[cfg(all(unix, target_env = "gnu"))] +#[cfg(all(unix, target_env = "gnu", not(target_os = "hurd")))] fn openat_via_syscall( dirfd: BorrowedFd<'_>, path: &CStr, @@ -188,7 +204,7 @@ pub(crate) fn openat( ) -> 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"))] + #[cfg(all(unix, target_env = "gnu", not(target_os = "hurd")))] if oflags.contains(OFlags::TMPFILE) && crate::backend::if_glibc_is_less_than_2_25() { return openat_via_syscall(dirfd, path, oflags, mode); } @@ -227,6 +243,7 @@ pub(crate) fn openat( target_os = "netbsd", target_os = "nto", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] #[inline] @@ -258,7 +275,10 @@ pub(crate) fn readlink(path: &CStr, buf: &mut [u8]) -> io::Result<usize> { } } -#[cfg(all(feature = "alloc", not(target_os = "redox")))] +#[cfg(all( + any(feature = "alloc", all(linux_kernel, feature = "procfs")), + not(target_os = "redox") +))] #[inline] pub(crate) fn readlinkat( dirfd: BorrowedFd<'_>, @@ -501,8 +521,6 @@ pub(crate) fn renameat2( } } -/// At present, `libc` only has `renameat2` defined for glibc. On other -/// ABIs, `RenameFlags` has no flags defined, and we use plain `renameat`. #[cfg(any( target_os = "android", all(target_os = "linux", not(target_env = "gnu")), @@ -515,8 +533,32 @@ pub(crate) fn renameat2( new_path: &CStr, flags: RenameFlags, ) -> io::Result<()> { - assert!(flags.is_empty()); - renameat(old_dirfd, old_path, new_dirfd, new_path) + // At present, `libc` only has `renameat2` defined for glibc. If we have + // no flags, we can use plain `renameat`, but otherwise we use `syscall!`. + // to call `renameat2` ourselves. + if flags.is_empty() { + renameat(old_dirfd, old_path, new_dirfd, new_path) + } else { + syscall! { + fn renameat2( + olddirfd: c::c_int, + oldpath: *const c::c_char, + newdirfd: c::c_int, + newpath: *const c::c_char, + flags: c::c_uint + ) via SYS_renameat2 -> c::c_int + } + + unsafe { + ret(renameat2( + borrowed_fd(old_dirfd), + c_str(old_path), + borrowed_fd(new_dirfd), + c_str(new_path), + flags.bits(), + )) + } + } } pub(crate) fn symlink(old_path: &CStr, new_path: &CStr) -> io::Result<()> { @@ -680,12 +722,17 @@ fn statat_old(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result< } } -#[cfg(not(any(target_os = "espidf", target_os = "emscripten")))] +#[cfg(not(any(target_os = "espidf", target_os = "emscripten", target_os = "vita")))] pub(crate) fn access(path: &CStr, access: Access) -> io::Result<()> { unsafe { ret(c::access(c_str(path), access.bits())) } } -#[cfg(not(any(target_os = "emscripten", target_os = "espidf", target_os = "redox")))] +#[cfg(not(any( + target_os = "emscripten", + target_os = "espidf", + target_os = "redox", + target_os = "vita" +)))] pub(crate) fn accessat( dirfd: BorrowedFd<'_>, path: &CStr, @@ -751,7 +798,7 @@ pub(crate) fn accessat( Ok(()) } -#[cfg(not(any(target_os = "espidf", target_os = "redox")))] +#[cfg(not(any(target_os = "espidf", target_os = "redox", target_os = "vita")))] pub(crate) fn utimensat( dirfd: BorrowedFd<'_>, path: &CStr, @@ -831,8 +878,8 @@ pub(crate) fn utimensat( )); } - // `setattrlistat` was introduced in 10.13 along with `utimensat`, so if - // we don't have `utimensat`, we don't have `setattrlistat` either. + // `setattrlistat` was introduced in 10.13 along with `utimensat`, so + // if we don't have `utimensat`, we don't have `setattrlistat` either. // Emulate it using `fork`, and `fchdir` and [`setattrlist`]. // // [`setattrlist`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setattrlist.2.html @@ -925,7 +972,11 @@ fn utimensat_old( .tv_sec .try_into() .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times.last_access.tv_nsec, + tv_nsec: times + .last_access + .tv_nsec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, }, c::timespec { tv_sec: times @@ -933,7 +984,11 @@ fn utimensat_old( .tv_sec .try_into() .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times.last_modification.tv_nsec, + tv_nsec: times + .last_modification + .tv_nsec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, }, ]; unsafe { @@ -1054,7 +1109,13 @@ pub(crate) fn chownat( } } -#[cfg(not(any(apple, target_os = "espidf", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any( + apple, + target_os = "espidf", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] pub(crate) fn mknodat( dirfd: BorrowedFd<'_>, path: &CStr, @@ -1133,6 +1194,7 @@ pub(crate) fn copy_file_range( target_os = "espidf", target_os = "haiku", target_os = "redox", + target_os = "vita", )))] pub(crate) fn fadvise(fd: BorrowedFd<'_>, offset: u64, len: u64, advice: Advice) -> io::Result<()> { let offset = offset as i64; @@ -1189,6 +1251,7 @@ pub(crate) fn fcntl_add_seals(fd: BorrowedFd<'_>, seals: SealFlags) -> io::Resul target_os = "espidf", target_os = "fuchsia", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] #[inline] @@ -1234,8 +1297,8 @@ pub(crate) fn seek(fd: BorrowedFd<'_>, pos: SeekFrom) -> io::Result<u64> { SeekFrom::Hole(offset) => (c::SEEK_HOLE, offset), }; - // ESP-IDF doesn't support 64-bit offsets. - #[cfg(target_os = "espidf")] + // ESP-IDF and Vita don't support 64-bit offsets. + #[cfg(any(target_os = "espidf", target_os = "vita"))] let offset: i32 = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; let offset = unsafe { ret_off_t(c::lseek(borrowed_fd(fd), offset, whence))? }; @@ -1302,7 +1365,12 @@ pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Option<Uid>, group: Option<Gid>) } } -#[cfg(not(any(target_os = "espidf", target_os = "solaris", target_os = "wasi")))] +#[cfg(not(any( + target_os = "espidf", + target_os = "solaris", + target_os = "vita", + target_os = "wasi" +)))] pub(crate) fn flock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::Result<()> { unsafe { ret(c::flock(borrowed_fd(fd), operation as c::c_int)) } } @@ -1324,7 +1392,12 @@ pub(crate) fn syncfs(fd: BorrowedFd<'_>) -> io::Result<()> { unsafe { ret(syncfs(borrowed_fd(fd))) } } -#[cfg(not(any(target_os = "espidf", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any( + target_os = "espidf", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] pub(crate) fn sync() { unsafe { c::sync() } } @@ -1392,6 +1465,7 @@ fn fstat_old(fd: BorrowedFd<'_>) -> io::Result<Stat> { target_os = "netbsd", target_os = "nto", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] pub(crate) fn fstatfs(fd: BorrowedFd<'_>) -> io::Result<StatFs> { @@ -1431,7 +1505,7 @@ fn libc_statvfs_to_statvfs(from: c::statvfs) -> StatVfs { } } -#[cfg(not(target_os = "espidf"))] +#[cfg(not(any(target_os = "espidf", target_os = "vita")))] pub(crate) fn futimens(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> { // Old 32-bit version: libc has `futimens` but it is not y2038 safe by // default. But there may be a `__futimens64` we can use. @@ -1507,7 +1581,11 @@ fn futimens_old(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> { .tv_sec .try_into() .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times.last_access.tv_nsec, + tv_nsec: times + .last_access + .tv_nsec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, }, c::timespec { tv_sec: times @@ -1515,7 +1593,11 @@ fn futimens_old(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> { .tv_sec .try_into() .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times.last_modification.tv_nsec, + tv_nsec: times + .last_modification + .tv_nsec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, }, ]; @@ -1531,6 +1613,7 @@ fn futimens_old(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> { target_os = "espidf", target_os = "nto", target_os = "redox", + target_os = "vita", )))] pub(crate) fn fallocate( fd: BorrowedFd<'_>, @@ -1557,7 +1640,8 @@ pub(crate) fn fallocate( assert!(mode.is_empty()); let err = unsafe { c::posix_fallocate(borrowed_fd(fd), offset, len) }; - // `posix_fallocate` returns its error status rather than using `errno`. + // `posix_fallocate` returns its error status rather than using + // `errno`. if err == 0 { Ok(()) } else { @@ -1607,6 +1691,7 @@ pub(crate) fn fsync(fd: BorrowedFd<'_>) -> io::Result<()> { target_os = "espidf", target_os = "haiku", target_os = "redox", + target_os = "vita", )))] pub(crate) fn fdatasync(fd: BorrowedFd<'_>) -> io::Result<()> { unsafe { ret(c::fdatasync(borrowed_fd(fd))) } diff --git a/vendor/rustix/src/backend/libc/fs/types.rs b/vendor/rustix/src/backend/libc/fs/types.rs index cf86861dc..876757715 100644 --- a/vendor/rustix/src/backend/libc/fs/types.rs +++ b/vendor/rustix/src/backend/libc/fs/types.rs @@ -1,7 +1,7 @@ use crate::backend::c; use bitflags::bitflags; -#[cfg(not(target_os = "espidf"))] +#[cfg(not(any(target_os = "espidf", target_os = "vita")))] bitflags! { /// `*_OK` constants for use with [`accessat`]. /// @@ -21,7 +21,7 @@ bitflags! { /// `F_OK` const EXISTS = c::F_OK; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -77,7 +77,7 @@ bitflags! { #[cfg(all(target_os = "linux", target_env = "gnu"))] const STATX_DONT_SYNC = bitcast!(c::AT_STATX_DONT_SYNC); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -92,66 +92,66 @@ bitflags! { #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct Mode: RawMode { /// `S_IRWXU` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const RWXU = c::S_IRWXU as RawMode; /// `S_IRUSR` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const RUSR = c::S_IRUSR as RawMode; /// `S_IWUSR` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const WUSR = c::S_IWUSR as RawMode; /// `S_IXUSR` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const XUSR = c::S_IXUSR as RawMode; /// `S_IRWXG` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const RWXG = c::S_IRWXG as RawMode; /// `S_IRGRP` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const RGRP = c::S_IRGRP as RawMode; /// `S_IWGRP` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const WGRP = c::S_IWGRP as RawMode; /// `S_IXGRP` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const XGRP = c::S_IXGRP as RawMode; /// `S_IRWXO` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const RWXO = c::S_IRWXO as RawMode; /// `S_IROTH` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const ROTH = c::S_IROTH as RawMode; /// `S_IWOTH` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const WOTH = c::S_IWOTH as RawMode; /// `S_IXOTH` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const XOTH = c::S_IXOTH as RawMode; /// `S_ISUID` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const SUID = c::S_ISUID as RawMode; /// `S_ISGID` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const SGID = c::S_ISGID as RawMode; /// `S_ISVTX` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const SVTX = c::S_ISVTX as RawMode; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -213,9 +213,9 @@ bitflags! { /// Similar to `ACCMODE`, but just includes the read/write flags, and /// no other flags. /// - /// Some implementations include `O_PATH` in `O_ACCMODE`, when + /// On some platforms, `PATH` may be included in `ACCMODE`, when /// sometimes we really just want the read/write bits. Caution is - /// indicated, as the presence of `O_PATH` may mean that the read/write + /// indicated, as the presence of `PATH` may mean that the read/write /// bits don't have their usual meaning. const RWMODE = bitcast!(c::O_RDONLY | c::O_WRONLY | c::O_RDWR); @@ -231,7 +231,7 @@ bitflags! { const DIRECTORY = bitcast!(c::O_DIRECTORY); /// `O_DSYNC` - #[cfg(not(any(target_os = "dragonfly", target_os = "espidf", target_os = "l4re", target_os = "redox")))] + #[cfg(not(any(target_os = "dragonfly", target_os = "espidf", target_os = "l4re", target_os = "redox", target_os = "vita")))] const DSYNC = bitcast!(c::O_DSYNC); /// `O_EXCL` @@ -263,7 +263,7 @@ bitflags! { const RDWR = bitcast!(c::O_RDWR); /// `O_NOCTTY` - #[cfg(not(any(target_os = "espidf", target_os = "l4re", target_os = "redox")))] + #[cfg(not(any(target_os = "espidf", target_os = "l4re", target_os = "redox", target_os = "vita")))] const NOCTTY = bitcast!(c::O_NOCTTY); /// `O_RSYNC` @@ -328,7 +328,7 @@ bitflags! { #[cfg(target_os = "freebsd")] const EMPTY_PATH = bitcast!(c::O_EMPTY_PATH); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -347,7 +347,7 @@ bitflags! { /// `CLONE_NOOWNERCOPY` const NOOWNERCOPY = 2; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -392,7 +392,7 @@ bitflags! { /// `COPYFILE_ALL` const ALL = copyfile::ALL; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -423,7 +423,7 @@ bitflags! { /// `RESOLVE_CACHED` (since Linux 5.12) const CACHED = 0x20; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -445,7 +445,7 @@ bitflags! { /// `RENAME_WHITEOUT` const WHITEOUT = bitcast!(c::RENAME_WHITEOUT); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -527,7 +527,8 @@ impl FileType { target_os = "espidf", target_os = "haiku", target_os = "nto", - target_os = "redox" + target_os = "redox", + target_os = "vita" )))] #[inline] pub(crate) const fn from_dirent_d_type(d_type: u8) -> Self { @@ -558,6 +559,7 @@ impl FileType { target_os = "espidf", target_os = "haiku", target_os = "redox", + target_os = "vita", )))] #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[repr(u32)] @@ -623,7 +625,7 @@ bitflags! { /// `MFD_HUGE_16GB` const HUGE_16GB = c::MFD_HUGE_16GB; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -638,19 +640,19 @@ bitflags! { #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct SealFlags: u32 { - /// `F_SEAL_SEAL`. + /// `F_SEAL_SEAL` const SEAL = bitcast!(c::F_SEAL_SEAL); - /// `F_SEAL_SHRINK`. + /// `F_SEAL_SHRINK` const SHRINK = bitcast!(c::F_SEAL_SHRINK); - /// `F_SEAL_GROW`. + /// `F_SEAL_GROW` const GROW = bitcast!(c::F_SEAL_GROW); - /// `F_SEAL_WRITE`. + /// `F_SEAL_WRITE` const WRITE = bitcast!(c::F_SEAL_WRITE); /// `F_SEAL_FUTURE_WRITE` (since Linux 5.1) #[cfg(linux_kernel)] const FUTURE_WRITE = bitcast!(c::F_SEAL_FUTURE_WRITE); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -711,7 +713,7 @@ bitflags! { /// `STATX_ALL` const ALL = c::STATX_ALL; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -772,7 +774,7 @@ bitflags! { /// `STATX_ALL` const ALL = 0xfff; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -783,7 +785,8 @@ bitflags! { target_os = "aix", target_os = "espidf", target_os = "nto", - target_os = "redox" + target_os = "redox", + target_os = "vita" )))] bitflags! { /// `FALLOC_FL_*` constants for use with [`fallocate`]. @@ -797,6 +800,7 @@ bitflags! { bsd, target_os = "aix", target_os = "haiku", + target_os = "hurd", target_os = "wasi", )))] const KEEP_SIZE = bitcast!(c::FALLOC_FL_KEEP_SIZE); @@ -805,6 +809,7 @@ bitflags! { bsd, target_os = "aix", target_os = "haiku", + target_os = "hurd", target_os = "wasi", )))] const PUNCH_HOLE = bitcast!(c::FALLOC_FL_PUNCH_HOLE); @@ -815,6 +820,7 @@ bitflags! { target_os = "emscripten", target_os = "fuchsia", target_os = "haiku", + target_os = "hurd", target_os = "l4re", target_os = "linux", target_os = "wasi", @@ -825,6 +831,7 @@ bitflags! { bsd, target_os = "aix", target_os = "haiku", + target_os = "hurd", target_os = "emscripten", target_os = "wasi", )))] @@ -834,6 +841,7 @@ bitflags! { bsd, target_os = "aix", target_os = "haiku", + target_os = "hurd", target_os = "emscripten", target_os = "wasi", )))] @@ -843,6 +851,7 @@ bitflags! { bsd, target_os = "aix", target_os = "haiku", + target_os = "hurd", target_os = "emscripten", target_os = "wasi", )))] @@ -852,12 +861,13 @@ bitflags! { bsd, target_os = "aix", target_os = "haiku", + target_os = "hurd", target_os = "emscripten", target_os = "wasi", )))] const UNSHARE_RANGE = bitcast!(c::FALLOC_FL_UNSHARE_RANGE); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -894,11 +904,11 @@ bitflags! { const NOEXEC = c::ST_NOEXEC as u64; /// `ST_NOSUID` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const NOSUID = c::ST_NOSUID as u64; /// `ST_RDONLY` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] const RDONLY = c::ST_RDONLY as u64; /// `ST_RELATIME` @@ -909,7 +919,7 @@ bitflags! { #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] const SYNCHRONOUS = c::ST_SYNCHRONOUS as u64; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -918,7 +928,7 @@ bitflags! { /// /// [`flock`]: crate::fs::flock /// [`fcntl_lock`]: crate::fs::fcntl_lock -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] +#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[repr(u32)] pub enum FlockOperation { @@ -940,7 +950,7 @@ pub enum FlockOperation { /// /// [`statat`]: crate::fs::statat /// [`fstat`]: crate::fs::fstat -#[cfg(not(linux_like))] +#[cfg(not(any(linux_like, target_os = "hurd")))] pub type Stat = c::stat; /// `struct stat` for use with [`statat`] and [`fstat`]. @@ -949,6 +959,7 @@ pub type Stat = c::stat; /// [`fstat`]: crate::fs::fstat #[cfg(any( all(linux_kernel, target_pointer_width = "64"), + target_os = "hurd", target_os = "emscripten", target_os = "l4re", ))] @@ -996,6 +1007,7 @@ pub struct Stat { target_os = "netbsd", target_os = "nto", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] #[allow(clippy::module_name_repetitions)] diff --git a/vendor/rustix/src/backend/libc/io/errno.rs b/vendor/rustix/src/backend/libc/io/errno.rs index 1448fe7bd..731086b4f 100644 --- a/vendor/rustix/src/backend/libc/io/errno.rs +++ b/vendor/rustix/src/backend/libc/io/errno.rs @@ -52,7 +52,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const ADV: Self = Self(c::EADV); @@ -74,7 +76,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const BADE: Self = Self(c::EBADE); @@ -87,7 +91,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const BADFD: Self = Self(c::EBADFD); @@ -101,7 +107,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const BADR: Self = Self(c::EBADR); @@ -115,7 +123,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const BADRQC: Self = Self(c::EBADRQC); @@ -126,7 +136,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const BADSLT: Self = Self(c::EBADSLT); @@ -137,7 +149,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const BFONT: Self = Self(c::EBFONT); @@ -159,7 +173,9 @@ impl Errno { windows, target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi" )))] pub const CHRNG: Self = Self(c::ECHRNG); @@ -170,7 +186,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const COMM: Self = Self(c::ECOMM); @@ -191,6 +209,8 @@ impl Errno { target_os = "android", target_os = "espidf", target_os = "haiku", + target_os = "hurd", + target_os = "vita", target_os = "wasi", )))] pub const DEADLOCK: Self = Self(c::EDEADLOCK); @@ -214,8 +234,10 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", target_os = "nto", + target_os = "vita", target_os = "wasi", )))] pub const DOTDOT: Self = Self(c::EDOTDOT); @@ -246,9 +268,11 @@ impl Errno { target_os = "android", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", target_os = "nto", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] pub const HWPOISON: Self = Self(c::EHWPOISON); @@ -293,8 +317,10 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", target_os = "nto", + target_os = "vita", target_os = "wasi", )))] pub const ISNAM: Self = Self(c::EISNAM); @@ -306,8 +332,10 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", target_os = "nto", + target_os = "vita", target_os = "wasi", )))] pub const KEYEXPIRED: Self = Self(c::EKEYEXPIRED); @@ -319,8 +347,10 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", target_os = "nto", + target_os = "vita", target_os = "wasi", )))] pub const KEYREJECTED: Self = Self(c::EKEYREJECTED); @@ -332,8 +362,10 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", target_os = "nto", + target_os = "vita", target_os = "wasi", )))] pub const KEYREVOKED: Self = Self(c::EKEYREVOKED); @@ -343,7 +375,9 @@ impl Errno { windows, target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi" )))] pub const L2HLT: Self = Self(c::EL2HLT); @@ -353,7 +387,9 @@ impl Errno { windows, target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi" )))] pub const L2NSYNC: Self = Self(c::EL2NSYNC); @@ -363,7 +399,9 @@ impl Errno { windows, target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi" )))] pub const L3HLT: Self = Self(c::EL3HLT); @@ -373,7 +411,9 @@ impl Errno { windows, target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi" )))] pub const L3RST: Self = Self(c::EL3RST); @@ -384,7 +424,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const LIBACC: Self = Self(c::ELIBACC); @@ -395,7 +437,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const LIBBAD: Self = Self(c::ELIBBAD); @@ -407,6 +451,7 @@ impl Errno { target_os = "espidf", target_os = "haiku", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const LIBEXEC: Self = Self(c::ELIBEXEC); @@ -417,7 +462,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const LIBMAX: Self = Self(c::ELIBMAX); @@ -428,7 +475,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const LIBSCN: Self = Self(c::ELIBSCN); @@ -438,7 +487,9 @@ impl Errno { windows, target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi" )))] pub const LNRNG: Self = Self(c::ELNRNG); @@ -452,8 +503,10 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", target_os = "nto", + target_os = "vita", target_os = "wasi", )))] pub const MEDIUMTYPE: Self = Self(c::EMEDIUMTYPE); @@ -478,8 +531,10 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", target_os = "nto", + target_os = "vita", target_os = "wasi", )))] pub const NAVAIL: Self = Self(c::ENAVAIL); @@ -503,7 +558,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const NOANO: Self = Self(c::ENOANO); @@ -519,7 +576,9 @@ impl Errno { windows, target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi" )))] pub const NOCSI: Self = Self(c::ENOCSI); @@ -549,8 +608,10 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", target_os = "nto", + target_os = "vita", target_os = "wasi", )))] pub const NOKEY: Self = Self(c::ENOKEY); @@ -568,8 +629,10 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", target_os = "nto", + target_os = "vita", target_os = "wasi", )))] pub const NOMEDIUM: Self = Self(c::ENOMEDIUM); @@ -589,7 +652,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const NONET: Self = Self(c::ENONET); @@ -600,7 +665,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const NOPKG: Self = Self(c::ENOPKG); @@ -634,7 +701,13 @@ impl Errno { #[cfg(not(windows))] pub const NOSYS: Self = Self(c::ENOSYS); /// `ENOTBLK` - #[cfg(not(any(windows, target_os = "espidf", target_os = "haiku", target_os = "wasi")))] + #[cfg(not(any( + windows, + target_os = "espidf", + target_os = "haiku", + target_os = "vita", + target_os = "wasi" + )))] pub const NOTBLK: Self = Self(c::ENOTBLK); /// `ENOTCAPABLE` #[cfg(any(target_os = "freebsd", target_os = "wasi"))] @@ -654,8 +727,10 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", target_os = "nto", + target_os = "vita", target_os = "wasi", )))] pub const NOTNAM: Self = Self(c::ENOTNAM); @@ -684,7 +759,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const NOTUNIQ: Self = Self(c::ENOTUNIQ); @@ -751,7 +828,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const REMCHG: Self = Self(c::EREMCHG); @@ -760,6 +839,7 @@ impl Errno { target_os = "espidf", target_os = "haiku", target_os = "l4re", + target_os = "vita", target_os = "wasi" )))] pub const REMOTE: Self = Self(c::EREMOTE); @@ -771,8 +851,10 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", target_os = "nto", + target_os = "vita", target_os = "wasi", )))] pub const REMOTEIO: Self = Self(c::EREMOTEIO); @@ -782,7 +864,9 @@ impl Errno { windows, target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi" )))] pub const RESTART: Self = Self(c::ERESTART); @@ -795,9 +879,11 @@ impl Errno { target_os = "android", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", target_os = "nto", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] pub const RFKILL: Self = Self(c::ERFKILL); @@ -808,13 +894,19 @@ impl Errno { #[cfg(bsd)] pub const RPCMISMATCH: Self = Self(c::ERPCMISMATCH); /// `ESHUTDOWN` - #[cfg(not(any(target_os = "espidf", target_os = "l4re", target_os = "wasi")))] + #[cfg(not(any( + target_os = "espidf", + target_os = "l4re", + target_os = "vita", + target_os = "wasi" + )))] pub const SHUTDOWN: Self = Self(c::ESHUTDOWN); /// `ESOCKTNOSUPPORT` #[cfg(not(any( target_os = "espidf", target_os = "haiku", target_os = "l4re", + target_os = "vita", target_os = "wasi" )))] pub const SOCKTNOSUPPORT: Self = Self(c::ESOCKTNOSUPPORT); @@ -831,7 +923,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const SRMNT: Self = Self(c::ESRMNT); @@ -844,7 +938,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const STRPIPE: Self = Self(c::ESTRPIPE); @@ -877,8 +973,10 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", target_os = "nto", + target_os = "vita", target_os = "wasi", )))] pub const UCLEAN: Self = Self(c::EUCLEAN); @@ -888,7 +986,9 @@ impl Errno { windows, target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi" )))] pub const UNATCH: Self = Self(c::EUNATCH); @@ -897,6 +997,7 @@ impl Errno { target_os = "espidf", target_os = "haiku", target_os = "l4re", + target_os = "vita", target_os = "wasi" )))] pub const USERS: Self = Self(c::EUSERS); @@ -912,7 +1013,9 @@ impl Errno { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "l4re", + target_os = "vita", target_os = "wasi", )))] pub const XFULL: Self = Self(c::EXFULL); diff --git a/vendor/rustix/src/backend/libc/io/syscalls.rs b/vendor/rustix/src/backend/libc/io/syscalls.rs index 19ecfa9b6..8d5aefadc 100644 --- a/vendor/rustix/src/backend/libc/io/syscalls.rs +++ b/vendor/rustix/src/backend/libc/io/syscalls.rs @@ -9,6 +9,7 @@ use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd}; target_os = "aix", target_os = "espidf", target_os = "nto", + target_os = "vita", target_os = "wasi" )))] use crate::io::DupFlags; @@ -51,8 +52,8 @@ pub(crate) fn pread(fd: BorrowedFd<'_>, buf: &mut [u8], offset: u64) -> io::Resu // Silently cast; we'll get `EINVAL` if the value is negative. let offset = offset as i64; - // ESP-IDF doesn't support 64-bit offsets. - #[cfg(target_os = "espidf")] + // ESP-IDF and Vita don't support 64-bit offsets. + #[cfg(any(target_os = "espidf", target_os = "vita"))] let offset: i32 = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; unsafe { @@ -71,8 +72,8 @@ 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; - // ESP-IDF doesn't support 64-bit offsets. - #[cfg(target_os = "espidf")] + // ESP-IDF and Vita don't support 64-bit offsets. + #[cfg(any(target_os = "espidf", target_os = "vita"))] let offset: i32 = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; unsafe { ret_usize(c::pwrite(borrowed_fd(fd), buf.as_ptr().cast(), len, offset)) } @@ -105,7 +106,8 @@ pub(crate) fn writev(fd: BorrowedFd<'_>, bufs: &[IoSlice<'_>]) -> io::Result<usi target_os = "haiku", target_os = "nto", target_os = "redox", - target_os = "solaris" + target_os = "solaris", + target_os = "vita" )))] pub(crate) fn preadv( fd: BorrowedFd<'_>, @@ -129,7 +131,8 @@ pub(crate) fn preadv( target_os = "haiku", target_os = "nto", target_os = "redox", - target_os = "solaris" + target_os = "solaris", + target_os = "vita" )))] pub(crate) fn pwritev(fd: BorrowedFd<'_>, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> { // Silently cast; we'll get `EINVAL` if the value is negative. @@ -316,6 +319,7 @@ pub(crate) fn dup2(fd: BorrowedFd<'_>, new: &mut OwnedFd) -> io::Result<()> { target_os = "haiku", target_os = "nto", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] pub(crate) fn dup3(fd: BorrowedFd<'_>, new: &mut OwnedFd, flags: DupFlags) -> io::Result<()> { diff --git a/vendor/rustix/src/backend/libc/io/types.rs b/vendor/rustix/src/backend/libc/io/types.rs index eaf3eae71..510206f98 100644 --- a/vendor/rustix/src/backend/libc/io/types.rs +++ b/vendor/rustix/src/backend/libc/io/types.rs @@ -12,7 +12,7 @@ bitflags! { /// `FD_CLOEXEC` const CLOEXEC = bitcast!(c::FD_CLOEXEC); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -37,7 +37,7 @@ bitflags! { /// `RWF_APPEND` (since Linux 4.16) const APPEND = linux_raw_sys::general::RWF_APPEND; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -59,7 +59,7 @@ bitflags! { )))] // Android 5.0 has dup3, but libc doesn't have bindings const CLOEXEC = bitcast!(c::O_CLOEXEC); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/libc/mm/syscalls.rs b/vendor/rustix/src/backend/libc/mm/syscalls.rs index 4b23a58b7..33bc9cac1 100644 --- a/vendor/rustix/src/backend/libc/mm/syscalls.rs +++ b/vendor/rustix/src/backend/libc/mm/syscalls.rs @@ -2,6 +2,8 @@ #[cfg(not(target_os = "redox"))] use super::types::Advice; +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +use super::types::MlockAllFlags; #[cfg(any(target_os = "emscripten", target_os = "linux"))] use super::types::MremapFlags; use super::types::{MapFlags, MprotectFlags, MsyncFlags, ProtFlags}; @@ -220,3 +222,23 @@ pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result<OwnedFd> } ret_owned_fd(userfaultfd(bitflags_bits!(flags))) } + +/// Locks all pages mapped into the address space of the calling process. +/// +/// This includes the pages of the code, data, and stack segment, as well as +/// shared libraries, user space kernel data, shared memory, and memory-mapped +/// files. All mapped pages are guaranteed to be resident in RAM when the call +/// returns successfully; the pages are guaranteed to stay in RAM until later +/// unlocked. +#[inline] +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +pub(crate) fn mlockall(flags: MlockAllFlags) -> io::Result<()> { + unsafe { ret(c::mlockall(bitflags_bits!(flags))) } +} + +/// Unlocks all pages mapped into the address space of the calling process. +#[inline] +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +pub(crate) fn munlockall() -> io::Result<()> { + unsafe { ret(c::munlockall()) } +} diff --git a/vendor/rustix/src/backend/libc/mm/types.rs b/vendor/rustix/src/backend/libc/mm/types.rs index f0b4ad593..ef335d27a 100644 --- a/vendor/rustix/src/backend/libc/mm/types.rs +++ b/vendor/rustix/src/backend/libc/mm/types.rs @@ -17,7 +17,7 @@ bitflags! { /// `PROT_EXEC` const EXEC = bitcast!(c::PROT_EXEC); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -59,7 +59,7 @@ bitflags! { #[cfg(all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64")))] const ADI = linux_raw_sys::general::PROT_ADI; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -231,7 +231,7 @@ bitflags! { #[cfg(any())] const UNINITIALIZED = bitcast!(c::MAP_UNINITIALIZED); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -250,7 +250,7 @@ bitflags! { /// `MREMAP_MAYMOVE` const MAYMOVE = bitcast!(c::MREMAP_MAYMOVE); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -272,7 +272,7 @@ bitflags! { /// written). const INVALIDATE = bitcast!(c::MS_INVALIDATE); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -288,7 +288,7 @@ bitflags! { /// `MLOCK_ONFAULT` const ONFAULT = bitcast!(c::MLOCK_ONFAULT); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -438,7 +438,31 @@ bitflags! { /// `O_NONBLOCK` const NONBLOCK = bitcast!(c::O_NONBLOCK); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> + const _ = !0; + } +} + +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +bitflags! { + /// `MCL_*` flags for use with [`mlockall`]. + /// + /// [`mlockall`]: crate::mm::mlockall + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct MlockAllFlags: u32 { + // libc doesn't define `MCL_ONFAULT` yet. + // const ONFAULT = libc::MCL_ONFAULT; + /// Lock all pages which will become mapped into the address space of + /// the process in the future. These could be, for instance, new pages + /// required by a growing heap and stack as well as new memory-mapped + /// files or shared memory regions. + const FUTURE = bitcast!(libc::MCL_FUTURE); + /// Lock all pages which are currently mapped into the address space of + /// the process. + const CURRENT = bitcast!(libc::MCL_CURRENT); + + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/libc/mod.rs b/vendor/rustix/src/backend/libc/mod.rs index 59fc3bea1..729eb2489 100644 --- a/vendor/rustix/src/backend/libc/mod.rs +++ b/vendor/rustix/src/backend/libc/mod.rs @@ -111,7 +111,7 @@ pub(crate) mod io; #[cfg(linux_kernel)] #[cfg(feature = "io_uring")] pub(crate) mod io_uring; -#[cfg(not(any(windows, target_os = "espidf", target_os = "wasi")))] +#[cfg(not(any(windows, target_os = "espidf", target_os = "vita", target_os = "wasi")))] #[cfg(feature = "mm")] pub(crate) mod mm; #[cfg(linux_kernel)] @@ -148,7 +148,7 @@ pub(crate) mod rand; #[cfg(not(target_os = "wasi"))] #[cfg(feature = "system")] pub(crate) mod system; -#[cfg(not(windows))] +#[cfg(not(any(windows, target_os = "vita")))] #[cfg(feature = "termios")] pub(crate) mod termios; #[cfg(not(windows))] @@ -184,6 +184,15 @@ pub(crate) mod pid; #[cfg(any(feature = "process", feature = "thread"))] #[cfg(linux_kernel)] pub(crate) mod prctl; +#[cfg(not(any( + windows, + target_os = "android", + target_os = "espidf", + target_os = "vita", + target_os = "wasi" +)))] +#[cfg(feature = "shm")] +pub(crate) mod shm; #[cfg(any(feature = "fs", feature = "thread", feature = "process"))] #[cfg(not(any(windows, target_os = "wasi")))] pub(crate) mod ugid; diff --git a/vendor/rustix/src/backend/libc/mount/types.rs b/vendor/rustix/src/backend/libc/mount/types.rs index 069a94444..d4f9c2da7 100644 --- a/vendor/rustix/src/backend/libc/mount/types.rs +++ b/vendor/rustix/src/backend/libc/mount/types.rs @@ -55,7 +55,7 @@ bitflags! { /// `MS_SYNCHRONOUS` const SYNCHRONOUS = c::MS_SYNCHRONOUS; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -77,7 +77,7 @@ bitflags! { /// `UMOUNT_NOFOLLOW` const NOFOLLOW = bitcast!(c::UMOUNT_NOFOLLOW); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -92,9 +92,9 @@ bitflags! { #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct FsOpenFlags: c::c_uint { /// `FSOPEN_CLOEXEC` - const FSOPEN_CLOEXEC = 0x00000001; + const FSOPEN_CLOEXEC = 0x0000_0001; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -109,9 +109,9 @@ bitflags! { #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct FsMountFlags: c::c_uint { /// `FSMOUNT_CLOEXEC` - const FSMOUNT_CLOEXEC = 0x00000001; + const FSMOUNT_CLOEXEC = 0x0000_0001; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -157,42 +157,42 @@ bitflags! { #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MountAttrFlags: c::c_uint { /// `MOUNT_ATTR_RDONLY` - const MOUNT_ATTR_RDONLY = 0x00000001; + const MOUNT_ATTR_RDONLY = 0x0000_0001; /// `MOUNT_ATTR_NOSUID` - const MOUNT_ATTR_NOSUID = 0x00000002; + const MOUNT_ATTR_NOSUID = 0x0000_0002; /// `MOUNT_ATTR_NODEV` - const MOUNT_ATTR_NODEV = 0x00000004; + const MOUNT_ATTR_NODEV = 0x0000_0004; /// `MOUNT_ATTR_NOEXEC` - const MOUNT_ATTR_NOEXEC = 0x00000008; + const MOUNT_ATTR_NOEXEC = 0x0000_0008; /// `MOUNT_ATTR__ATIME` - const MOUNT_ATTR__ATIME = 0x00000070; + const MOUNT_ATTR__ATIME = 0x0000_0070; /// `MOUNT_ATTR_RELATIME` - const MOUNT_ATTR_RELATIME = 0x00000000; + const MOUNT_ATTR_RELATIME = 0x0000_0000; /// `MOUNT_ATTR_NOATIME` - const MOUNT_ATTR_NOATIME = 0x00000010; + const MOUNT_ATTR_NOATIME = 0x0000_0010; /// `MOUNT_ATTR_STRICTATIME` - const MOUNT_ATTR_STRICTATIME = 0x00000020; + const MOUNT_ATTR_STRICTATIME = 0x0000_0020; /// `MOUNT_ATTR_NODIRATIME` - const MOUNT_ATTR_NODIRATIME = 0x00000080; + const MOUNT_ATTR_NODIRATIME = 0x0000_0080; /// `MOUNT_ATTR_NOUSER` - const MOUNT_ATTR_IDMAP = 0x00100000; + const MOUNT_ATTR_IDMAP = 0x0010_0000; /// `MOUNT_ATTR__ATIME_FLAGS` - const MOUNT_ATTR_NOSYMFOLLOW = 0x00200000; + const MOUNT_ATTR_NOSYMFOLLOW = 0x0020_0000; /// `MOUNT_ATTR__ATIME_FLAGS` const MOUNT_ATTR_SIZE_VER0 = 32; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -207,34 +207,34 @@ bitflags! { #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MoveMountFlags: c::c_uint { /// `MOVE_MOUNT_F_EMPTY_PATH` - const MOVE_MOUNT_F_SYMLINKS = 0x00000001; + const MOVE_MOUNT_F_SYMLINKS = 0x0000_0001; /// `MOVE_MOUNT_F_AUTOMOUNTS` - const MOVE_MOUNT_F_AUTOMOUNTS = 0x00000002; + const MOVE_MOUNT_F_AUTOMOUNTS = 0x0000_0002; /// `MOVE_MOUNT_F_EMPTY_PATH` - const MOVE_MOUNT_F_EMPTY_PATH = 0x00000004; + const MOVE_MOUNT_F_EMPTY_PATH = 0x0000_0004; /// `MOVE_MOUNT_T_SYMLINKS` - const MOVE_MOUNT_T_SYMLINKS = 0x00000010; + const MOVE_MOUNT_T_SYMLINKS = 0x0000_0010; /// `MOVE_MOUNT_T_AUTOMOUNTS` - const MOVE_MOUNT_T_AUTOMOUNTS = 0x00000020; + const MOVE_MOUNT_T_AUTOMOUNTS = 0x0000_0020; /// `MOVE_MOUNT_T_EMPTY_PATH` - const MOVE_MOUNT_T_EMPTY_PATH = 0x00000040; + const MOVE_MOUNT_T_EMPTY_PATH = 0x0000_0040; /// `MOVE_MOUNT__MASK` - const MOVE_MOUNT_SET_GROUP = 0x00000100; + const MOVE_MOUNT_SET_GROUP = 0x0000_0100; // TODO: add when linux 6.5 is released // /// `MOVE_MOUNT_BENEATH` - // const MOVE_MOUNT_BENEATH = 0x00000200; + // const MOVE_MOUNT_BENEATH = 0x0000_0200; /// `MOVE_MOUNT__MASK` - const MOVE_MOUNT__MASK = 0x00000377; + const MOVE_MOUNT__MASK = 0x0000_0377; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -266,7 +266,7 @@ bitflags! { /// `AT_SYMLINK_NOFOLLOW` const AT_SYMLINK_NOFOLLOW = c::AT_SYMLINK_NOFOLLOW as c::c_uint; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -281,18 +281,18 @@ bitflags! { #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct FsPickFlags: c::c_uint { /// `FSPICK_CLOEXEC` - const FSPICK_CLOEXEC = 0x00000001; + const FSPICK_CLOEXEC = 0x0000_0001; /// `FSPICK_SYMLINK_NOFOLLOW` - const FSPICK_SYMLINK_NOFOLLOW = 0x00000002; + const FSPICK_SYMLINK_NOFOLLOW = 0x0000_0002; /// `FSPICK_NO_AUTOMOUNT` - const FSPICK_NO_AUTOMOUNT = 0x00000004; + const FSPICK_NO_AUTOMOUNT = 0x0000_0004; /// `FSPICK_EMPTY_PATH` - const FSPICK_EMPTY_PATH = 0x00000008; + const FSPICK_EMPTY_PATH = 0x0000_0008; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -318,7 +318,7 @@ bitflags! { /// `MS_REC` const REC = c::MS_REC; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -331,7 +331,7 @@ bitflags! { const REMOUNT = c::MS_REMOUNT; const MOVE = c::MS_MOVE; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/libc/net/addr.rs b/vendor/rustix/src/backend/libc/net/addr.rs index 6a140d767..719a549b1 100644 --- a/vendor/rustix/src/backend/libc/net/addr.rs +++ b/vendor/rustix/src/backend/libc/net/addr.rs @@ -78,6 +78,8 @@ impl SocketAddrUnix { c::sockaddr_un { #[cfg(any(bsd, target_os = "aix", target_os = "haiku", target_os = "nto"))] sun_len: 0, + #[cfg(target_os = "vita")] + ss_len: 0, sun_family: c::AF_UNIX as _, #[cfg(any(bsd, target_os = "nto"))] sun_path: [0; 104], @@ -210,12 +212,15 @@ pub(crate) fn offsetof_sun_path() -> usize { let z = c::sockaddr_un { #[cfg(any(bsd, target_os = "aix", target_os = "haiku", target_os = "nto"))] sun_len: 0_u8, + #[cfg(target_os = "vita")] + ss_len: 0, #[cfg(any( bsd, target_os = "aix", target_os = "espidf", target_os = "haiku", - target_os = "nto" + target_os = "nto", + target_os = "vita" ))] sun_family: 0_u8, #[cfg(not(any( @@ -223,7 +228,8 @@ pub(crate) fn offsetof_sun_path() -> usize { target_os = "aix", target_os = "espidf", target_os = "haiku", - target_os = "nto" + target_os = "nto", + target_os = "vita" )))] sun_family: 0_u16, #[cfg(any(bsd, target_os = "nto"))] diff --git a/vendor/rustix/src/backend/libc/net/ext.rs b/vendor/rustix/src/backend/libc/net/ext.rs index eb7c20d7d..2e11c051d 100644 --- a/vendor/rustix/src/backend/libc/net/ext.rs +++ b/vendor/rustix/src/backend/libc/net/ext.rs @@ -83,7 +83,8 @@ pub(crate) const fn sockaddr_in6_new( target_os = "aix", target_os = "espidf", target_os = "haiku", - target_os = "nto" + target_os = "nto", + target_os = "vita" ))] sin6_len: u8, sin6_family: c::sa_family_t, @@ -98,7 +99,8 @@ pub(crate) const fn sockaddr_in6_new( target_os = "aix", target_os = "espidf", target_os = "haiku", - target_os = "nto" + target_os = "nto", + target_os = "vita" ))] sin6_len, sin6_family, @@ -108,6 +110,8 @@ pub(crate) const fn sockaddr_in6_new( sin6_scope_id, #[cfg(solarish)] __sin6_src_id: 0, + #[cfg(target_os = "vita")] + sin6_vport: 0, } } diff --git a/vendor/rustix/src/backend/libc/net/mod.rs b/vendor/rustix/src/backend/libc/net/mod.rs index 65c7d0654..d7ab68d52 100644 --- a/vendor/rustix/src/backend/libc/net/mod.rs +++ b/vendor/rustix/src/backend/libc/net/mod.rs @@ -1,8 +1,16 @@ pub(crate) mod addr; pub(crate) mod ext; -#[cfg(not(any(windows, target_os = "espidf", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any( + windows, + target_os = "espidf", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] pub(crate) mod msghdr; pub(crate) mod read_sockaddr; pub(crate) mod send_recv; +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) mod sockopt; pub(crate) mod syscalls; pub(crate) mod write_sockaddr; diff --git a/vendor/rustix/src/backend/libc/net/msghdr.rs b/vendor/rustix/src/backend/libc/net/msghdr.rs index 2ccd7f20c..dd9b156a5 100644 --- a/vendor/rustix/src/backend/libc/net/msghdr.rs +++ b/vendor/rustix/src/backend/libc/net/msghdr.rs @@ -114,7 +114,7 @@ pub(crate) fn with_unix_msghdr<R>( ) -> R { f({ let mut h = zero_msghdr(); - h.msg_name = as_ptr(addr) as _; + h.msg_name = as_ptr(&addr.unix) as _; h.msg_namelen = addr.addr_len(); h.msg_iov = iov.as_ptr() as _; h.msg_iovlen = msg_iov_len(iov.len()); diff --git a/vendor/rustix/src/backend/libc/net/read_sockaddr.rs b/vendor/rustix/src/backend/libc/net/read_sockaddr.rs index 604f24928..6da7a50dd 100644 --- a/vendor/rustix/src/backend/libc/net/read_sockaddr.rs +++ b/vendor/rustix/src/backend/libc/net/read_sockaddr.rs @@ -1,5 +1,5 @@ -//! 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. +//! 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; @@ -14,14 +14,40 @@ use core::mem::size_of; // This must match the header of `sockaddr`. #[repr(C)] struct sockaddr_header { - #[cfg(any(bsd, target_os = "haiku"))] + #[cfg(any( + bsd, + target_os = "aix", + target_os = "espidf", + target_os = "haiku", + target_os = "nto", + target_os = "vita" + ))] sa_len: u8, - #[cfg(any(bsd, target_os = "haiku"))] + #[cfg(any( + bsd, + target_os = "aix", + target_os = "espidf", + target_os = "haiku", + target_os = "nto", + target_os = "vita" + ))] ss_family: u8, - #[cfg(not(any(bsd, target_os = "haiku")))] + #[cfg(not(any( + bsd, + target_os = "aix", + target_os = "espidf", + target_os = "haiku", + target_os = "nto", + target_os = "vita" + )))] ss_family: u16, } +/// Read the `ss_family` field from a socket address returned from the OS. +/// +/// # Safety +/// +/// `storage` must point to a valid socket address returned from the OS. #[inline] unsafe fn read_ss_family(storage: *const c::sockaddr_storage) -> u16 { // Assert that we know the layout of `sockaddr`. @@ -31,7 +57,8 @@ unsafe fn read_ss_family(storage: *const c::sockaddr_storage) -> u16 { target_os = "aix", target_os = "espidf", target_os = "haiku", - target_os = "nto" + target_os = "nto", + target_os = "vita" ))] sa_len: 0_u8, #[cfg(any( @@ -39,7 +66,8 @@ unsafe fn read_ss_family(storage: *const c::sockaddr_storage) -> u16 { target_os = "aix", target_os = "espidf", target_os = "haiku", - target_os = "nto" + target_os = "nto", + target_os = "vita" ))] sa_family: 0_u8, #[cfg(not(any( @@ -47,7 +75,8 @@ unsafe fn read_ss_family(storage: *const c::sockaddr_storage) -> u16 { target_os = "aix", target_os = "espidf", target_os = "haiku", - target_os = "nto" + target_os = "nto", + target_os = "vita" )))] sa_family: 0_u16, #[cfg(not(target_os = "haiku"))] @@ -138,10 +167,10 @@ pub(crate) unsafe fn read_sockaddr( // 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. + let path_bytes = if cfg!(any(solarish, target_os = "freebsd")) { + // FreeBSD and illumos sometimes set the length to longer + // than the length of the NUL-terminated string. Find the + // NUL and truncate the string accordingly. &decode.sun_path[..decode .sun_path .iter() @@ -168,6 +197,11 @@ pub(crate) unsafe fn read_sockaddr( } } +/// Read an optional socket address returned from the OS. +/// +/// # Safety +/// +/// `storage` must point to a valid socket address returned from the OS. pub(crate) unsafe fn maybe_read_sockaddr_os( storage: *const c::sockaddr_storage, len: usize, @@ -185,6 +219,11 @@ pub(crate) unsafe fn maybe_read_sockaddr_os( } } +/// Read a socket address returned from the OS. +/// +/// # Safety +/// +/// `storage` must point to a valid socket address returned from the OS. pub(crate) unsafe fn read_sockaddr_os( storage: *const c::sockaddr_storage, len: usize, @@ -250,10 +289,10 @@ unsafe fn inner_read_sockaddr_os( 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 - // of the NUL-terminated string. Find the NUL and truncate the - // string accordingly. - #[cfg(target_os = "freebsd")] + // FreeBSD and illumos sometimes set the length to longer than + // the length of the NUL-terminated string. Find the NUL and + // truncate the string accordingly. + #[cfg(any(solarish, target_os = "freebsd"))] let path_bytes = &path_bytes[..path_bytes.iter().position(|b| *b == 0).unwrap()]; SocketAddrAny::Unix( diff --git a/vendor/rustix/src/backend/libc/net/send_recv.rs b/vendor/rustix/src/backend/libc/net/send_recv.rs index 76dc97e78..5dc60ddcd 100644 --- a/vendor/rustix/src/backend/libc/net/send_recv.rs +++ b/vendor/rustix/src/backend/libc/net/send_recv.rs @@ -2,7 +2,8 @@ use crate::backend::c; use bitflags::bitflags; bitflags! { - /// `MSG_* flags for use with [`send`], [`send_to`], and related functions. + /// `MSG_*` flags for use with [`send`], [`send_to`], and related + /// functions. /// /// [`send`]: crate::net::send /// [`sendto`]: crate::net::sendto @@ -18,6 +19,7 @@ bitflags! { target_os = "espidf", target_os = "nto", target_os = "haiku", + target_os = "vita", )))] const CONFIRM = bitcast!(c::MSG_CONFIRM); /// `MSG_DONTROUTE` @@ -36,21 +38,23 @@ bitflags! { target_os = "aix", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] const MORE = bitcast!(c::MSG_MORE); - #[cfg(not(any(apple, windows)))] + #[cfg(not(any(apple, windows, target_os = "vita")))] /// `MSG_NOSIGNAL` const NOSIGNAL = bitcast!(c::MSG_NOSIGNAL); /// `MSG_OOB` const OOB = bitcast!(c::MSG_OOB); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } bitflags! { - /// `MSG_* flags for use with [`recv`], [`recvfrom`], and related functions. + /// `MSG_*` flags for use with [`recv`], [`recvfrom`], and related + /// functions. /// /// [`recv`]: crate::net::recv /// [`recvfrom`]: crate::net::recvfrom @@ -65,6 +69,7 @@ bitflags! { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] /// `MSG_CMSG_CLOEXEC` const CMSG_CLOEXEC = bitcast!(c::MSG_CMSG_CLOEXEC); @@ -80,6 +85,7 @@ bitflags! { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] const ERRQUEUE = bitcast!(c::MSG_ERRQUEUE); /// `MSG_OOB` @@ -91,7 +97,7 @@ bitflags! { /// `MSG_WAITALL` const WAITALL = bitcast!(c::MSG_WAITALL); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/libc/net/sockopt.rs b/vendor/rustix/src/backend/libc/net/sockopt.rs new file mode 100644 index 000000000..cff2ca288 --- /dev/null +++ b/vendor/rustix/src/backend/libc/net/sockopt.rs @@ -0,0 +1,1065 @@ +//! libc syscalls supporting `rustix::net::sockopt`. + +use super::ext::{in6_addr_new, in_addr_new}; +use crate::backend::c; +use crate::backend::conv::{borrowed_fd, ret}; +use crate::fd::BorrowedFd; +#[cfg(feature = "alloc")] +#[cfg(any( + linux_like, + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos" +))] +use crate::ffi::CStr; +use crate::io; +use crate::net::sockopt::Timeout; +#[cfg(not(any( + apple, + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "espidf", + target_os = "haiku", + target_os = "netbsd", + target_os = "nto", + target_os = "vita", +)))] +use crate::net::AddressFamily; +#[cfg(any( + linux_kernel, + target_os = "freebsd", + target_os = "fuchsia", + target_os = "openbsd", + target_os = "redox", + target_env = "newlib" +))] +use crate::net::Protocol; +#[cfg(any( + linux_kernel, + target_os = "freebsd", + target_os = "fuchsia", + target_os = "openbsd", + target_os = "redox", + target_env = "newlib" +))] +use crate::net::RawProtocol; +use crate::net::{Ipv4Addr, Ipv6Addr, SocketType}; +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +use crate::net::{SocketAddrAny, SocketAddrStorage, SocketAddrV4}; +#[cfg(linux_kernel)] +use crate::net::{SocketAddrV6, UCred}; +use crate::utils::as_mut_ptr; +#[cfg(feature = "alloc")] +#[cfg(any( + linux_like, + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos" +))] +use alloc::borrow::ToOwned; +#[cfg(feature = "alloc")] +#[cfg(any( + linux_like, + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos" +))] +use alloc::string::String; +#[cfg(apple)] +use c::TCP_KEEPALIVE as TCP_KEEPIDLE; +#[cfg(not(any(apple, target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +use c::TCP_KEEPIDLE; +use core::mem::{size_of, MaybeUninit}; +use core::time::Duration; +#[cfg(windows)] +use windows_sys::Win32::Foundation::BOOL; + +#[inline] +fn getsockopt<T: Copy>(fd: BorrowedFd<'_>, level: i32, optname: i32) -> io::Result<T> { + let mut optlen = core::mem::size_of::<T>().try_into().unwrap(); + debug_assert!( + optlen as usize >= core::mem::size_of::<c::c_int>(), + "Socket APIs don't ever use `bool` directly" + ); + + let mut value = MaybeUninit::<T>::zeroed(); + getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; + + // On Windows at least, `getsockopt` has been observed writing 1 + // byte on at least (`IPPROTO_TCP`, `TCP_NODELAY`), even though + // Windows' documentation says that should write a 4-byte `BOOL`. + // So, we initialize the memory to zeros above, and just assert + // that `getsockopt` doesn't write too many bytes here. + assert!( + optlen as usize <= size_of::<T>(), + "unexpected getsockopt size" + ); + + unsafe { Ok(value.assume_init()) } +} + +#[inline] +fn getsockopt_raw<T>( + fd: BorrowedFd<'_>, + level: i32, + optname: i32, + value: &mut MaybeUninit<T>, + optlen: &mut c::socklen_t, +) -> io::Result<()> { + unsafe { + ret(c::getsockopt( + borrowed_fd(fd), + level, + optname, + as_mut_ptr(value).cast(), + optlen, + )) + } +} + +#[inline] +fn setsockopt<T: Copy>(fd: BorrowedFd<'_>, level: i32, optname: i32, value: T) -> io::Result<()> { + let optlen = core::mem::size_of::<T>().try_into().unwrap(); + debug_assert!( + optlen as usize >= core::mem::size_of::<c::c_int>(), + "Socket APIs don't ever use `bool` directly" + ); + setsockopt_raw(fd, level, optname, &value, optlen) +} + +#[inline] +fn setsockopt_raw<T>( + fd: BorrowedFd<'_>, + level: i32, + optname: i32, + ptr: *const T, + optlen: c::socklen_t, +) -> io::Result<()> { + unsafe { + ret(c::setsockopt( + borrowed_fd(fd), + level, + optname, + ptr.cast(), + optlen, + )) + } +} + +#[inline] +pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result<SocketType> { + getsockopt(fd, c::SOL_SOCKET, c::SO_TYPE) +} + +#[inline] +pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR, from_bool(reuseaddr)) +} + +#[inline] +pub(crate) fn get_socket_reuseaddr(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST, from_bool(broadcast)) +} + +#[inline] +pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_linger(fd: BorrowedFd<'_>, linger: Option<Duration>) -> io::Result<()> { + // Convert `linger` to seconds, rounding up. + let l_linger = if let Some(linger) = linger { + duration_to_secs(linger)? + } else { + 0 + }; + let linger = c::linger { + l_onoff: linger.is_some().into(), + l_linger, + }; + setsockopt(fd, c::SOL_SOCKET, c::SO_LINGER, linger) +} + +#[inline] +pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result<Option<Duration>> { + let linger: c::linger = getsockopt(fd, c::SOL_SOCKET, c::SO_LINGER)?; + Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) +} + +#[cfg(linux_kernel)] +#[inline] +pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED, from_bool(passcred)) +} + +#[cfg(linux_kernel)] +#[inline] +pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_timeout( + fd: BorrowedFd<'_>, + id: Timeout, + timeout: Option<Duration>, +) -> io::Result<()> { + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO, + Timeout::Send => c::SO_SNDTIMEO, + }; + + #[cfg(not(windows))] + let timeout = match timeout { + Some(timeout) => { + if timeout == Duration::ZERO { + return Err(io::Errno::INVAL); + } + + // Rust's musl libc bindings deprecated `time_t` while they + // transition to 64-bit `time_t`. What we want here is just + // “whatever type `timeval`'s `tv_sec` is”, so we're ok using + // the deprecated type. + #[allow(deprecated)] + let tv_sec = timeout.as_secs().try_into().unwrap_or(c::time_t::MAX); + + // `subsec_micros` rounds down, so we use `subsec_nanos` and + // manually round up. + let mut timeout = c::timeval { + tv_sec, + tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, + }; + if timeout.tv_sec == 0 && timeout.tv_usec == 0 { + timeout.tv_usec = 1; + } + timeout + } + None => c::timeval { + tv_sec: 0, + tv_usec: 0, + }, + }; + + #[cfg(windows)] + let timeout: u32 = match timeout { + Some(timeout) => { + if timeout == Duration::ZERO { + return Err(io::Errno::INVAL); + } + + // `as_millis` rounds down, so we use `as_nanos` and + // manually round up. + let mut timeout: u32 = ((timeout.as_nanos() + 999_999) / 1_000_000) + .try_into() + .map_err(|_convert_err| io::Errno::INVAL)?; + if timeout == 0 { + timeout = 1; + } + timeout + } + None => 0, + }; + + setsockopt(fd, c::SOL_SOCKET, optname, timeout) +} + +#[inline] +pub(crate) fn get_socket_timeout(fd: BorrowedFd<'_>, id: Timeout) -> io::Result<Option<Duration>> { + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO, + Timeout::Send => c::SO_SNDTIMEO, + }; + + #[cfg(not(windows))] + { + let timeout: c::timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; + if timeout.tv_sec == 0 && timeout.tv_usec == 0 { + Ok(None) + } else { + Ok(Some( + Duration::from_secs(timeout.tv_sec as u64) + + Duration::from_micros(timeout.tv_usec as u64), + )) + } + } + + #[cfg(windows)] + { + let timeout: u32 = getsockopt(fd, c::SOL_SOCKET, optname)?; + if timeout == 0 { + Ok(None) + } else { + Ok(Some(Duration::from_millis(timeout as u64))) + } + } +} + +#[cfg(any(apple, freebsdlike, target_os = "netbsd"))] +#[inline] +pub(crate) fn get_socket_nosigpipe(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::SOL_SOCKET, c::SO_NOSIGPIPE).map(to_bool) +} + +#[cfg(any(apple, freebsdlike, target_os = "netbsd"))] +#[inline] +pub(crate) fn set_socket_nosigpipe(fd: BorrowedFd<'_>, val: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_NOSIGPIPE, from_bool(val)) +} + +#[inline] +pub(crate) fn get_socket_error(fd: BorrowedFd<'_>) -> io::Result<Result<(), io::Errno>> { + let err: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_ERROR)?; + Ok(if err == 0 { + Ok(()) + } else { + Err(io::Errno::from_raw_os_error(err)) + }) +} + +#[inline] +pub(crate) fn set_socket_keepalive(fd: BorrowedFd<'_>, keepalive: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE, from_bool(keepalive)) +} + +#[inline] +pub(crate) fn get_socket_keepalive(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { + let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; + setsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF, size) +} + +#[inline] +pub(crate) fn get_socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result<usize> { + getsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF).map(|size: u32| size as usize) +} + +#[inline] +pub(crate) fn set_socket_send_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { + let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; + setsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF, size) +} + +#[inline] +pub(crate) fn get_socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result<usize> { + getsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF).map(|size: u32| size as usize) +} + +#[inline] +#[cfg(not(any( + apple, + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "espidf", + target_os = "haiku", + target_os = "netbsd", + target_os = "nto", + target_os = "vita", +)))] +pub(crate) fn get_socket_domain(fd: BorrowedFd<'_>) -> io::Result<AddressFamily> { + let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_DOMAIN)?; + Ok(AddressFamily( + domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?, + )) +} + +#[inline] +#[cfg(not(apple))] // Apple platforms declare the constant, but do not actually implement it. +pub(crate) fn get_socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::SOL_SOCKET, c::SO_ACCEPTCONN).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_oobinline(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE, from_bool(value)) +} + +#[inline] +pub(crate) fn get_socket_oobinline(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE).map(to_bool) +} + +#[cfg(not(any(solarish, windows)))] +#[inline] +pub(crate) fn set_socket_reuseport(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT, from_bool(value)) +} + +#[cfg(not(any(solarish, windows)))] +#[inline] +pub(crate) fn get_socket_reuseport(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT).map(to_bool) +} + +#[cfg(target_os = "freebsd")] +#[inline] +pub(crate) fn set_socket_reuseport_lb(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT_LB, from_bool(value)) +} + +#[cfg(target_os = "freebsd")] +#[inline] +pub(crate) fn get_socket_reuseport_lb(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT_LB).map(to_bool) +} + +#[cfg(any( + linux_kernel, + target_os = "freebsd", + target_os = "fuchsia", + target_os = "openbsd", + target_os = "redox", + target_env = "newlib" +))] +#[inline] +pub(crate) fn get_socket_protocol(fd: BorrowedFd<'_>) -> io::Result<Option<Protocol>> { + getsockopt(fd, c::SOL_SOCKET, c::SO_PROTOCOL) + .map(|raw| RawProtocol::new(raw).map(Protocol::from_raw)) +} + +#[cfg(target_os = "linux")] +#[inline] +pub(crate) fn get_socket_cookie(fd: BorrowedFd<'_>) -> io::Result<u64> { + getsockopt(fd, c::SOL_SOCKET, c::SO_COOKIE) +} + +#[cfg(target_os = "linux")] +#[inline] +pub(crate) fn get_socket_incoming_cpu(fd: BorrowedFd<'_>) -> io::Result<u32> { + getsockopt(fd, c::SOL_SOCKET, c::SO_INCOMING_CPU) +} + +#[cfg(target_os = "linux")] +#[inline] +pub(crate) fn set_socket_incoming_cpu(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_INCOMING_CPU, value) +} + +#[inline] +pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IP_TTL, ttl) +} + +#[inline] +pub(crate) fn get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result<u32> { + getsockopt(fd, c::IPPROTO_IP, c::IP_TTL) +} + +#[inline] +pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY, from_bool(only_v6)) +} + +#[inline] +pub(crate) fn get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY).map(to_bool) +} + +#[inline] +pub(crate) fn set_ip_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IP, + c::IP_MULTICAST_LOOP, + from_bool(multicast_loop), + ) +} + +#[inline] +pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_LOOP).map(to_bool) +} + +#[inline] +pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl) +} + +#[inline] +pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result<u32> { + getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL) +} + +#[inline] +pub(crate) fn set_ipv6_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IPV6, + c::IPV6_MULTICAST_LOOP, + from_bool(multicast_loop), + ) +} + +#[inline] +pub(crate) fn get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP).map(to_bool) +} + +#[inline] +pub(crate) fn set_ipv6_multicast_hops(fd: BorrowedFd<'_>, multicast_hops: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS, multicast_hops) +} + +#[inline] +pub(crate) fn get_ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result<u32> { + getsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS) +} + +#[inline] +pub(crate) fn set_ip_add_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, +) -> io::Result<()> { + let mreq = to_ip_mreq(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq) +} + +#[cfg(any( + apple, + freebsdlike, + linux_like, + target_os = "fuchsia", + target_os = "openbsd" +))] +#[inline] +pub(crate) fn set_ip_add_membership_with_ifindex( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + address: &Ipv4Addr, + ifindex: i32, +) -> io::Result<()> { + let mreqn = to_ip_mreqn(multiaddr, address, ifindex); + setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreqn) +} + +#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] +#[inline] +pub(crate) fn set_ip_add_source_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> io::Result<()> { + let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); + setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_SOURCE_MEMBERSHIP, mreq_source) +} + +#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] +#[inline] +pub(crate) fn set_ip_drop_source_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> io::Result<()> { + let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); + setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_SOURCE_MEMBERSHIP, mreq_source) +} + +#[inline] +pub(crate) fn set_ipv6_add_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv6Addr, + interface: u32, +) -> io::Result<()> { + #[cfg(not(any( + bsd, + solarish, + target_os = "haiku", + target_os = "l4re", + target_os = "nto" + )))] + use c::IPV6_ADD_MEMBERSHIP; + #[cfg(any( + bsd, + solarish, + target_os = "haiku", + target_os = "l4re", + target_os = "nto" + ))] + use c::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; + + let mreq = to_ipv6mr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn set_ip_drop_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, +) -> io::Result<()> { + let mreq = to_ip_mreq(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq) +} + +#[cfg(any( + apple, + freebsdlike, + linux_like, + target_os = "fuchsia", + target_os = "openbsd" +))] +#[inline] +pub(crate) fn set_ip_drop_membership_with_ifindex( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + address: &Ipv4Addr, + ifindex: i32, +) -> io::Result<()> { + let mreqn = to_ip_mreqn(multiaddr, address, ifindex); + setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreqn) +} + +#[inline] +pub(crate) fn set_ipv6_drop_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv6Addr, + interface: u32, +) -> io::Result<()> { + #[cfg(not(any( + bsd, + solarish, + target_os = "haiku", + target_os = "l4re", + target_os = "nto" + )))] + use c::IPV6_DROP_MEMBERSHIP; + #[cfg(any( + bsd, + solarish, + target_os = "haiku", + target_os = "l4re", + target_os = "nto" + ))] + use c::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; + + let mreq = to_ipv6mr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn get_ipv6_unicast_hops(fd: BorrowedFd<'_>) -> io::Result<u8> { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) +} + +#[inline] +pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option<u8>) -> io::Result<()> { + let hops = match hops { + Some(hops) => hops as c::c_int, + None => -1, + }; + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS, hops) +} + +#[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "haiku", + target_os = "nto", + target_env = "newlib" +))] +#[inline] +pub(crate) fn set_ip_tos(fd: BorrowedFd<'_>, value: u8) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IP_TOS, i32::from(value)) +} + +#[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "haiku", + target_os = "nto", + target_env = "newlib" +))] +#[inline] +pub(crate) fn get_ip_tos(fd: BorrowedFd<'_>) -> io::Result<u8> { + let value: i32 = getsockopt(fd, c::IPPROTO_IP, c::IP_TOS)?; + Ok(value as u8) +} + +#[cfg(any(apple, linux_like, target_os = "freebsd", target_os = "fuchsia"))] +#[inline] +pub(crate) fn set_ip_recvtos(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS, from_bool(value)) +} + +#[cfg(any(apple, linux_like, target_os = "freebsd", target_os = "fuchsia"))] +#[inline] +pub(crate) fn get_ip_recvtos(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS).map(to_bool) +} + +#[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "nto" +))] +#[inline] +pub(crate) fn set_ipv6_recvtclass(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS, from_bool(value)) +} + +#[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "nto" +))] +#[inline] +pub(crate) fn get_ipv6_recvtclass(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS).map(to_bool) +} + +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[inline] +pub(crate) fn set_ip_freebind(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IP_FREEBIND, from_bool(value)) +} + +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[inline] +pub(crate) fn get_ip_freebind(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_IP, c::IP_FREEBIND).map(to_bool) +} + +#[cfg(linux_kernel)] +#[inline] +pub(crate) fn set_ipv6_freebind(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_FREEBIND, from_bool(value)) +} + +#[cfg(linux_kernel)] +#[inline] +pub(crate) fn get_ipv6_freebind(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_FREEBIND).map(to_bool) +} + +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[inline] +pub(crate) fn get_ip_original_dst(fd: BorrowedFd<'_>) -> io::Result<SocketAddrV4> { + let level = c::IPPROTO_IP; + let optname = c::SO_ORIGINAL_DST; + let mut value = MaybeUninit::<SocketAddrStorage>::uninit(); + let mut optlen = core::mem::size_of_val(&value).try_into().unwrap(); + + getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; + + let any = unsafe { SocketAddrAny::read(value.as_ptr(), optlen as usize)? }; + match any { + SocketAddrAny::V4(v4) => Ok(v4), + _ => unreachable!(), + } +} + +#[cfg(linux_kernel)] +#[inline] +pub(crate) fn get_ipv6_original_dst(fd: BorrowedFd<'_>) -> io::Result<SocketAddrV6> { + let level = c::IPPROTO_IPV6; + let optname = c::IP6T_SO_ORIGINAL_DST; + let mut value = MaybeUninit::<SocketAddrStorage>::uninit(); + let mut optlen = core::mem::size_of_val(&value).try_into().unwrap(); + + getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; + + let any = unsafe { SocketAddrAny::read(value.as_ptr(), optlen as usize)? }; + match any { + SocketAddrAny::V6(v6) => Ok(v6), + _ => unreachable!(), + } +} + +#[cfg(not(any( + solarish, + windows, + target_os = "espidf", + target_os = "haiku", + target_os = "vita" +)))] +#[inline] +pub(crate) fn set_ipv6_tclass(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_TCLASS, value) +} + +#[cfg(not(any( + solarish, + windows, + target_os = "espidf", + target_os = "haiku", + target_os = "vita" +)))] +#[inline] +pub(crate) fn get_ipv6_tclass(fd: BorrowedFd<'_>) -> io::Result<u32> { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_TCLASS) +} + +#[inline] +pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY, from_bool(nodelay)) +} + +#[inline] +pub(crate) fn get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY).map(to_bool) +} + +#[inline] +#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT, count) +} + +#[inline] +#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +pub(crate) fn get_tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result<u32> { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT) +} + +#[inline] +#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { + let secs: c::c_uint = duration_to_secs(duration)?; + setsockopt(fd, c::IPPROTO_TCP, TCP_KEEPIDLE, secs) +} + +#[inline] +#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +pub(crate) fn get_tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result<Duration> { + let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, TCP_KEEPIDLE)?; + Ok(Duration::from_secs(secs as u64)) +} + +#[inline] +#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { + let secs: c::c_uint = duration_to_secs(duration)?; + setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL, secs) +} + +#[inline] +#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +pub(crate) fn get_tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result<Duration> { + let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL)?; + Ok(Duration::from_secs(secs as u64)) +} + +#[inline] +#[cfg(any(linux_like, target_os = "fuchsia"))] +pub(crate) fn set_tcp_user_timeout(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT, value) +} + +#[inline] +#[cfg(any(linux_like, target_os = "fuchsia"))] +pub(crate) fn get_tcp_user_timeout(fd: BorrowedFd<'_>) -> io::Result<u32> { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT) +} + +#[cfg(any(linux_like, target_os = "fuchsia"))] +#[inline] +pub(crate) fn set_tcp_quickack(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP, c::TCP_QUICKACK, from_bool(value)) +} + +#[cfg(any(linux_like, target_os = "fuchsia"))] +#[inline] +pub(crate) fn get_tcp_quickack(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_QUICKACK).map(to_bool) +} + +#[cfg(any( + linux_like, + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos" +))] +#[inline] +pub(crate) fn set_tcp_congestion(fd: BorrowedFd<'_>, value: &str) -> io::Result<()> { + let level = c::IPPROTO_TCP; + let optname = c::TCP_CONGESTION; + let optlen = value.len().try_into().unwrap(); + setsockopt_raw(fd, level, optname, value.as_ptr(), optlen) +} + +#[cfg(feature = "alloc")] +#[cfg(any( + linux_like, + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos" +))] +#[inline] +pub(crate) fn get_tcp_congestion(fd: BorrowedFd<'_>) -> io::Result<String> { + let level = c::IPPROTO_TCP; + let optname = c::TCP_CONGESTION; + const OPTLEN: c::socklen_t = 16; + let mut value = MaybeUninit::<[MaybeUninit<u8>; OPTLEN as usize]>::uninit(); + let mut optlen = OPTLEN; + getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; + unsafe { + let value = value.assume_init(); + let slice: &[u8] = core::mem::transmute(&value[..optlen as usize]); + assert!(slice.iter().any(|b| *b == b'\0')); + Ok( + core::str::from_utf8(CStr::from_ptr(slice.as_ptr().cast()).to_bytes()) + .unwrap() + .to_owned(), + ) + } +} + +#[cfg(any(linux_like, target_os = "fuchsia"))] +#[inline] +pub(crate) fn set_tcp_thin_linear_timeouts(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_TCP, + c::TCP_THIN_LINEAR_TIMEOUTS, + from_bool(value), + ) +} + +#[cfg(any(linux_like, target_os = "fuchsia"))] +#[inline] +pub(crate) fn get_tcp_thin_linear_timeouts(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_THIN_LINEAR_TIMEOUTS).map(to_bool) +} + +#[cfg(any(linux_like, solarish, target_os = "fuchsia"))] +#[inline] +pub(crate) fn set_tcp_cork(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP, c::TCP_CORK, from_bool(value)) +} + +#[cfg(any(linux_like, solarish, target_os = "fuchsia"))] +#[inline] +pub(crate) fn get_tcp_cork(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_CORK).map(to_bool) +} + +#[cfg(linux_kernel)] +#[inline] +pub(crate) fn get_socket_peercred(fd: BorrowedFd<'_>) -> io::Result<UCred> { + getsockopt(fd, c::SOL_SOCKET, c::SO_PEERCRED) +} + +#[inline] +fn to_ip_mreq(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { + c::ip_mreq { + imr_multiaddr: to_imr_addr(multiaddr), + imr_interface: to_imr_addr(interface), + } +} + +#[cfg(any( + apple, + freebsdlike, + linux_like, + target_os = "fuchsia", + target_os = "openbsd" +))] +#[inline] +fn to_ip_mreqn(multiaddr: &Ipv4Addr, address: &Ipv4Addr, ifindex: i32) -> c::ip_mreqn { + c::ip_mreqn { + imr_multiaddr: to_imr_addr(multiaddr), + imr_address: to_imr_addr(address), + imr_ifindex: ifindex, + } +} + +#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] +#[inline] +fn to_imr_source( + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> c::ip_mreq_source { + c::ip_mreq_source { + imr_multiaddr: to_imr_addr(multiaddr), + imr_interface: to_imr_addr(interface), + imr_sourceaddr: to_imr_addr(sourceaddr), + } +} + +#[inline] +fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { + in_addr_new(u32::from_ne_bytes(addr.octets())) +} + +#[inline] +fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { + c::ipv6_mreq { + ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), + ipv6mr_interface: to_ipv6mr_interface(interface), + } +} + +#[inline] +fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { + in6_addr_new(multiaddr.octets()) +} + +#[cfg(target_os = "android")] +#[inline] +fn to_ipv6mr_interface(interface: u32) -> c::c_int { + interface as c::c_int +} + +#[cfg(not(target_os = "android"))] +#[inline] +fn to_ipv6mr_interface(interface: u32) -> c::c_uint { + interface as c::c_uint +} + +// `getsockopt` and `setsockopt` represent boolean values as integers. +#[cfg(not(windows))] +type RawSocketBool = c::c_int; +#[cfg(windows)] +type RawSocketBool = BOOL; + +// Wrap `RawSocketBool` in a newtype to discourage misuse. +#[repr(transparent)] +#[derive(Copy, Clone)] +struct SocketBool(RawSocketBool); + +// Convert from a `bool` to a `SocketBool`. +#[inline] +fn from_bool(value: bool) -> SocketBool { + SocketBool(value.into()) +} + +// Convert from a `SocketBool` to a `bool`. +#[inline] +fn to_bool(value: SocketBool) -> bool { + value.0 != 0 +} + +/// Convert to seconds, rounding up if necessary. +#[inline] +fn duration_to_secs<T: TryFrom<u64>>(duration: Duration) -> io::Result<T> { + let mut secs = duration.as_secs(); + if duration.subsec_nanos() != 0 { + secs = secs.checked_add(1).ok_or(io::Errno::INVAL)?; + } + T::try_from(secs).map_err(|_e| io::Errno::INVAL) +} diff --git a/vendor/rustix/src/backend/libc/net/syscalls.rs b/vendor/rustix/src/backend/libc/net/syscalls.rs index 2e968ba3e..97b862033 100644 --- a/vendor/rustix/src/backend/libc/net/syscalls.rs +++ b/vendor/rustix/src/backend/libc/net/syscalls.rs @@ -2,7 +2,6 @@ #[cfg(unix)] use super::addr::SocketAddrUnix; -use super::ext::{in6_addr_new, in_addr_new}; 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}; @@ -10,7 +9,13 @@ use crate::io; use crate::net::{SocketAddrAny, SocketAddrV4, SocketAddrV6}; use crate::utils::as_ptr; use core::mem::{size_of, MaybeUninit}; -#[cfg(not(any(windows, target_os = "espidf", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any( + windows, + target_os = "espidf", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] use { super::msghdr::{with_noaddr_msghdr, with_recv_msghdr, with_v4_msghdr, with_v6_msghdr}, crate::io::{IoSlice, IoSliceMut}, @@ -244,6 +249,19 @@ pub(crate) fn connect_unix(sockfd: BorrowedFd<'_>, addr: &SocketAddrUnix) -> io: } #[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn connect_unspec(sockfd: BorrowedFd<'_>) -> io::Result<()> { + debug_assert_eq!(c::AF_UNSPEC, 0); + let addr = MaybeUninit::<c::sockaddr_storage>::zeroed(); + unsafe { + ret(c::connect( + borrowed_fd(sockfd), + as_ptr(&addr).cast(), + size_of::<c::sockaddr_storage>() as c::socklen_t, + )) + } +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] pub(crate) fn listen(sockfd: BorrowedFd<'_>, backlog: c::c_int) -> io::Result<()> { unsafe { ret(c::listen(borrowed_fd(sockfd), backlog)) } } @@ -256,7 +274,13 @@ pub(crate) fn accept(sockfd: BorrowedFd<'_>) -> io::Result<OwnedFd> { } } -#[cfg(not(any(windows, target_os = "espidf", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any( + windows, + target_os = "espidf", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] pub(crate) fn recvmsg( sockfd: BorrowedFd<'_>, iov: &mut [IoSliceMut<'_>], @@ -288,7 +312,13 @@ pub(crate) fn recvmsg( }) } -#[cfg(not(any(windows, target_os = "espidf", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any( + windows, + target_os = "espidf", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] pub(crate) fn sendmsg( sockfd: BorrowedFd<'_>, iov: &[IoSlice<'_>], @@ -304,7 +334,13 @@ pub(crate) fn sendmsg( }) } -#[cfg(not(any(windows, target_os = "espidf", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any( + windows, + target_os = "espidf", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] pub(crate) fn sendmsg_v4( sockfd: BorrowedFd<'_>, addr: &SocketAddrV4, @@ -321,7 +357,13 @@ pub(crate) fn sendmsg_v4( }) } -#[cfg(not(any(windows, target_os = "espidf", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any( + windows, + target_os = "espidf", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] pub(crate) fn sendmsg_v6( sockfd: BorrowedFd<'_>, addr: &SocketAddrV6, @@ -338,7 +380,10 @@ pub(crate) fn sendmsg_v6( }) } -#[cfg(all(unix, not(any(target_os = "espidf", target_os = "redox"))))] +#[cfg(all( + unix, + not(any(target_os = "espidf", target_os = "redox", target_os = "vita")) +))] pub(crate) fn sendmsg_unix( sockfd: BorrowedFd<'_>, addr: &SocketAddrUnix, @@ -363,6 +408,7 @@ pub(crate) fn sendmsg_unix( target_os = "haiku", target_os = "redox", target_os = "nto", + target_os = "vita", target_os = "wasi", )))] pub(crate) fn accept_with(sockfd: BorrowedFd<'_>, flags: SocketFlags) -> io::Result<OwnedFd> { @@ -402,6 +448,7 @@ pub(crate) fn acceptfrom(sockfd: BorrowedFd<'_>) -> io::Result<(OwnedFd, Option< target_os = "haiku", target_os = "nto", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] pub(crate) fn acceptfrom_with( @@ -432,7 +479,8 @@ pub(crate) fn acceptfrom_with( target_os = "aix", target_os = "espidf", target_os = "haiku", - target_os = "nto" + target_os = "nto", + target_os = "vita", ))] pub(crate) fn accept_with(sockfd: BorrowedFd<'_>, _flags: SocketFlags) -> io::Result<OwnedFd> { accept(sockfd) @@ -446,7 +494,8 @@ pub(crate) fn accept_with(sockfd: BorrowedFd<'_>, _flags: SocketFlags) -> io::Re target_os = "aix", target_os = "espidf", target_os = "haiku", - target_os = "nto" + target_os = "nto", + target_os = "vita", ))] pub(crate) fn acceptfrom_with( sockfd: BorrowedFd<'_>, @@ -515,636 +564,3 @@ pub(crate) fn socketpair( Ok((fd0, fd1)) } } - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) mod sockopt { - use super::{c, in6_addr_new, in_addr_new, BorrowedFd}; - use crate::io; - use crate::net::sockopt::Timeout; - #[cfg(not(any( - apple, - windows, - target_os = "aix", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "espidf", - target_os = "haiku", - target_os = "netbsd", - target_os = "nto", - )))] - use crate::net::AddressFamily; - use crate::net::{Ipv4Addr, Ipv6Addr, SocketType}; - use crate::utils::as_mut_ptr; - #[cfg(apple)] - use c::TCP_KEEPALIVE as TCP_KEEPIDLE; - #[cfg(not(any(apple, target_os = "openbsd", target_os = "haiku", target_os = "nto")))] - use c::TCP_KEEPIDLE; - use core::time::Duration; - #[cfg(windows)] - use windows_sys::Win32::Foundation::BOOL; - - #[inline] - fn getsockopt<T: Copy>(fd: BorrowedFd<'_>, level: i32, optname: i32) -> io::Result<T> { - use super::*; - - let mut optlen = core::mem::size_of::<T>().try_into().unwrap(); - debug_assert!( - optlen as usize >= core::mem::size_of::<c::c_int>(), - "Socket APIs don't ever use `bool` directly" - ); - - unsafe { - let mut value = core::mem::zeroed::<T>(); - ret(c::getsockopt( - borrowed_fd(fd), - level, - optname, - as_mut_ptr(&mut value).cast(), - &mut optlen, - ))?; - // On Windows at least, `getsockopt` has been observed writing 1 - // byte on at least (`IPPROTO_TCP`, `TCP_NODELAY`), even though - // Windows' documentation says that should write a 4-byte `BOOL`. - // So, we initialize the memory to zeros above, and just assert - // that `getsockopt` doesn't write too many bytes here. - assert!( - optlen as usize <= size_of::<T>(), - "unexpected getsockopt size" - ); - Ok(value) - } - } - - #[inline] - fn setsockopt<T: Copy>( - fd: BorrowedFd<'_>, - level: i32, - optname: i32, - value: T, - ) -> io::Result<()> { - use super::*; - - let optlen = core::mem::size_of::<T>().try_into().unwrap(); - debug_assert!( - optlen as usize >= core::mem::size_of::<c::c_int>(), - "Socket APIs don't ever use `bool` directly" - ); - - unsafe { - ret(c::setsockopt( - borrowed_fd(fd), - level, - optname, - as_ptr(&value).cast(), - optlen, - )) - } - } - - #[inline] - pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result<SocketType> { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_TYPE) - } - - #[inline] - pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_REUSEADDR, - from_bool(reuseaddr), - ) - } - - #[inline] - pub(crate) fn get_socket_reuseaddr(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_REUSEADDR).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_BROADCAST, - from_bool(broadcast), - ) - } - - #[inline] - pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_BROADCAST).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_linger( - fd: BorrowedFd<'_>, - linger: Option<Duration>, - ) -> io::Result<()> { - // Convert `linger` to seconds, rounding up. - let l_linger = if let Some(linger) = linger { - duration_to_secs(linger)? - } else { - 0 - }; - let linger = c::linger { - l_onoff: linger.is_some() as _, - l_linger, - }; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER, linger) - } - - #[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)?; - Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) - } - - #[cfg(linux_kernel)] - #[inline] - pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED, from_bool(passcred)) - } - - #[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) - } - - #[inline] - pub(crate) fn set_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option<Duration>, - ) -> io::Result<()> { - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO, - Timeout::Send => c::SO_SNDTIMEO, - }; - - #[cfg(not(windows))] - let timeout = match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - - // Rust's musl libc bindings deprecated `time_t` while they - // transition to 64-bit `time_t`. What we want here is just - // “whatever type `timeval`'s `tv_sec` is”, so we're ok using - // the deprecated type. - #[allow(deprecated)] - let tv_sec = timeout.as_secs().try_into().unwrap_or(c::time_t::MAX); - - // `subsec_micros` rounds down, so we use `subsec_nanos` and - // manually round up. - let mut timeout = c::timeval { - tv_sec, - tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => c::timeval { - tv_sec: 0, - tv_usec: 0, - }, - }; - - #[cfg(windows)] - let timeout: u32 = match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - - // `as_millis` rounds down, so we use `as_nanos` and - // manually round up. - let mut timeout: u32 = ((timeout.as_nanos() + 999_999) / 1_000_000) - .try_into() - .map_err(|_convert_err| io::Errno::INVAL)?; - if timeout == 0 { - timeout = 1; - } - timeout - } - None => 0, - }; - - setsockopt(fd, c::SOL_SOCKET, optname, timeout) - } - - #[inline] - pub(crate) fn get_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - ) -> io::Result<Option<Duration>> { - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO, - Timeout::Send => c::SO_SNDTIMEO, - }; - - #[cfg(not(windows))] - { - let timeout: c::timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - Ok(None) - } else { - Ok(Some( - Duration::from_secs(timeout.tv_sec as u64) - + Duration::from_micros(timeout.tv_usec as u64), - )) - } - } - - #[cfg(windows)] - { - let timeout: u32 = getsockopt(fd, c::SOL_SOCKET, optname)?; - if timeout == 0 { - Ok(None) - } else { - Ok(Some(Duration::from_millis(timeout as u64))) - } - } - } - - #[cfg(any(apple, target_os = "freebsd"))] - #[inline] - 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 set_socket_nosigpipe(fd: BorrowedFd<'_>, val: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_NOSIGPIPE, from_bool(val)) - } - - #[inline] - pub(crate) fn get_socket_error(fd: BorrowedFd<'_>) -> io::Result<Result<(), io::Errno>> { - let err: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_ERROR)?; - Ok(if err == 0 { - Ok(()) - } else { - Err(io::Errno::from_raw_os_error(err)) - }) - } - - #[inline] - pub(crate) fn set_socket_keepalive(fd: BorrowedFd<'_>, keepalive: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_KEEPALIVE, - from_bool(keepalive), - ) - } - - #[inline] - pub(crate) fn get_socket_keepalive(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_KEEPALIVE).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF, size) - } - - #[inline] - pub(crate) fn get_socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result<usize> { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF).map(|size: u32| size as usize) - } - - #[inline] - pub(crate) fn set_socket_send_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF, size) - } - - #[inline] - pub(crate) fn get_socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result<usize> { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF).map(|size: u32| size as usize) - } - - #[inline] - #[cfg(not(any( - apple, - windows, - target_os = "aix", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "espidf", - target_os = "haiku", - target_os = "netbsd", - target_os = "nto", - )))] - pub(crate) fn get_socket_domain(fd: BorrowedFd<'_>) -> io::Result<AddressFamily> { - let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_DOMAIN)?; - Ok(AddressFamily( - domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?, - )) - } - - #[inline] - #[cfg(not(apple))] // Apple platforms declare the constant, but do not actually implement it. - pub(crate) fn get_socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_ACCEPTCONN).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL, ttl) - } - - #[inline] - pub(crate) fn get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL) - } - - #[inline] - pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY, from_bool(only_v6)) - } - - #[inline] - pub(crate) fn get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_multicast_loop( - fd: BorrowedFd<'_>, - multicast_loop: bool, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP as _, - c::IP_MULTICAST_LOOP, - from_bool(multicast_loop), - ) - } - - #[inline] - pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_LOOP).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL, multicast_ttl) - } - - #[inline] - pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL) - } - - #[inline] - pub(crate) fn set_ipv6_multicast_loop( - fd: BorrowedFd<'_>, - multicast_loop: bool, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IPV6 as _, - c::IPV6_MULTICAST_LOOP, - from_bool(multicast_loop), - ) - } - - #[inline] - pub(crate) fn get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_MULTICAST_LOOP).map(to_bool) - } - - #[inline] - pub(crate) fn set_ipv6_multicast_hops( - fd: BorrowedFd<'_>, - multicast_hops: u32, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP as _, - 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_HOPS) - } - - #[inline] - pub(crate) fn set_ip_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_ADD_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ipv6_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, - ) -> io::Result<()> { - #[cfg(not(any( - bsd, - solarish, - target_os = "haiku", - target_os = "l4re", - target_os = "nto" - )))] - use c::IPV6_ADD_MEMBERSHIP; - #[cfg(any( - bsd, - solarish, - target_os = "haiku", - target_os = "l4re", - target_os = "nto" - ))] - use c::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; - - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, IPV6_ADD_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ip_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_DROP_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ipv6_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, - ) -> io::Result<()> { - #[cfg(not(any( - bsd, - solarish, - target_os = "haiku", - target_os = "l4re", - target_os = "nto" - )))] - use c::IPV6_DROP_MEMBERSHIP; - #[cfg(any( - bsd, - solarish, - target_os = "haiku", - target_os = "l4re", - target_os = "nto" - ))] - use c::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; - - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, IPV6_DROP_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn get_ipv6_unicast_hops(fd: BorrowedFd<'_>) -> io::Result<u8> { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) - } - - #[inline] - pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option<u8>) -> io::Result<()> { - let hops = match hops { - Some(hops) => hops as c::c_int, - None => -1, - }; - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS, hops) - } - - #[inline] - pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY, from_bool(nodelay)) - } - - #[inline] - pub(crate) fn get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY).map(to_bool) - } - - #[inline] - #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] - pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPCNT, count) - } - - #[inline] - #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] - pub(crate) fn get_tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPCNT) - } - - #[inline] - #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] - pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPIDLE, secs) - } - - #[inline] - #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] - pub(crate) fn get_tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result<Duration> { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPIDLE)?; - Ok(Duration::from_secs(secs as u64)) - } - - #[inline] - #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] - pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPINTVL, secs) - } - - #[inline] - #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] - pub(crate) fn get_tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result<Duration> { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_KEEPINTVL)?; - Ok(Duration::from_secs(secs as u64)) - } - - #[inline] - fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { - c::ip_mreq { - imr_multiaddr: to_imr_addr(multiaddr), - imr_interface: to_imr_addr(interface), - } - } - - #[inline] - fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { - in_addr_new(u32::from_ne_bytes(addr.octets())) - } - - #[inline] - fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { - c::ipv6_mreq { - ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), - ipv6mr_interface: to_ipv6mr_interface(interface), - } - } - - #[inline] - fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { - in6_addr_new(multiaddr.octets()) - } - - #[cfg(target_os = "android")] - #[inline] - fn to_ipv6mr_interface(interface: u32) -> c::c_int { - interface as c::c_int - } - - #[cfg(not(target_os = "android"))] - #[inline] - fn to_ipv6mr_interface(interface: u32) -> c::c_uint { - interface as c::c_uint - } - - // `getsockopt` and `setsockopt` represent boolean values as integers. - #[cfg(not(windows))] - type RawSocketBool = c::c_int; - #[cfg(windows)] - type RawSocketBool = BOOL; - - // Wrap `RawSocketBool` in a newtype to discourage misuse. - #[repr(transparent)] - #[derive(Copy, Clone)] - struct SocketBool(RawSocketBool); - - // Convert from a `bool` to a `SocketBool`. - #[inline] - fn from_bool(value: bool) -> SocketBool { - SocketBool(value as _) - } - - // Convert from a `SocketBool` to a `bool`. - #[inline] - fn to_bool(value: SocketBool) -> bool { - value.0 != 0 - } - - /// Convert to seconds, rounding up if necessary. - #[inline] - fn duration_to_secs<T: TryFrom<u64>>(duration: Duration) -> io::Result<T> { - let mut secs = duration.as_secs(); - if duration.subsec_nanos() != 0 { - secs = secs.checked_add(1).ok_or(io::Errno::INVAL)?; - } - T::try_from(secs).map_err(|_e| io::Errno::INVAL) - } -} diff --git a/vendor/rustix/src/backend/libc/net/write_sockaddr.rs b/vendor/rustix/src/backend/libc/net/write_sockaddr.rs index a354d9a85..2eee98cb8 100644 --- a/vendor/rustix/src/backend/libc/net/write_sockaddr.rs +++ b/vendor/rustix/src/backend/libc/net/write_sockaddr.rs @@ -1,5 +1,5 @@ -//! 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. +//! 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::addr::SocketAddrStorage; #[cfg(unix)] @@ -29,15 +29,20 @@ pub(crate) fn encode_sockaddr_v4(v4: &SocketAddrV4) -> c::sockaddr_in { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", ))] sin_len: size_of::<c::sockaddr_in>() as _, sin_family: c::AF_INET as _, sin_port: u16::to_be(v4.port()), sin_addr: in_addr_new(u32::from_ne_bytes(v4.ip().octets())), - #[cfg(not(target_os = "haiku"))] + #[cfg(not(any(target_os = "haiku", target_os = "vita")))] sin_zero: [0; 8_usize], #[cfg(target_os = "haiku")] sin_zero: [0; 24_usize], + #[cfg(target_os = "vita")] + sin_zero: [0; 6_usize], + #[cfg(target_os = "vita")] + sin_vport: 0, } } @@ -54,6 +59,7 @@ pub(crate) fn encode_sockaddr_v6(v6: &SocketAddrV6) -> c::sockaddr_in6 { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita" ))] { sockaddr_in6_new( @@ -70,7 +76,8 @@ pub(crate) fn encode_sockaddr_v6(v6: &SocketAddrV6) -> c::sockaddr_in6 { target_os = "aix", target_os = "espidf", target_os = "haiku", - target_os = "nto" + target_os = "nto", + target_os = "vita" )))] { sockaddr_in6_new( diff --git a/vendor/rustix/src/backend/libc/param/auxv.rs b/vendor/rustix/src/backend/libc/param/auxv.rs index 0eeb972cc..880a1d43f 100644 --- a/vendor/rustix/src/backend/libc/param/auxv.rs +++ b/vendor/rustix/src/backend/libc/param/auxv.rs @@ -17,7 +17,7 @@ pub(crate) fn page_size() -> usize { unsafe { c::sysconf(c::_SC_PAGESIZE) as usize } } -#[cfg(not(target_os = "wasi"))] +#[cfg(not(any(target_os = "vita", target_os = "wasi")))] #[inline] pub(crate) fn clock_ticks_per_second() -> u64 { unsafe { c::sysconf(c::_SC_CLK_TCK) as u64 } diff --git a/vendor/rustix/src/backend/libc/pipe/types.rs b/vendor/rustix/src/backend/libc/pipe/types.rs index 7f5634b17..1004e41f7 100644 --- a/vendor/rustix/src/backend/libc/pipe/types.rs +++ b/vendor/rustix/src/backend/libc/pipe/types.rs @@ -21,12 +21,13 @@ bitflags! { target_os = "nto", target_os = "openbsd", target_os = "redox", + target_os = "vita", )))] const DIRECT = bitcast!(c::O_DIRECT); /// `O_NONBLOCK` const NONBLOCK = bitcast!(c::O_NONBLOCK); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -47,7 +48,7 @@ bitflags! { /// `SPLICE_F_GIFT` const GIFT = c::SPLICE_F_GIFT; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/libc/process/mod.rs b/vendor/rustix/src/backend/libc/process/mod.rs index 4d9a9f0a0..b89096199 100644 --- a/vendor/rustix/src/backend/libc/process/mod.rs +++ b/vendor/rustix/src/backend/libc/process/mod.rs @@ -3,5 +3,5 @@ pub(crate) mod cpu_set; #[cfg(not(windows))] pub(crate) mod syscalls; pub(crate) mod types; -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] +#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] pub(crate) mod wait; diff --git a/vendor/rustix/src/backend/libc/process/syscalls.rs b/vendor/rustix/src/backend/libc/process/syscalls.rs index dd71801d5..ec31e0ea7 100644 --- a/vendor/rustix/src/backend/libc/process/syscalls.rs +++ b/vendor/rustix/src/backend/libc/process/syscalls.rs @@ -13,6 +13,7 @@ use crate::backend::conv::ret_discarded_char_ptr; target_os = "espidf", target_os = "fuchsia", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] use crate::backend::conv::ret_infallible; @@ -36,16 +37,24 @@ use crate::io; use crate::process::Gid; #[cfg(not(target_os = "wasi"))] use crate::process::Pid; -#[cfg(not(any(target_os = "espidf", target_os = "fuchsia", target_os = "wasi")))] +#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] +use crate::process::Signal; +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "vita", + target_os = "wasi" +)))] use crate::process::Uid; #[cfg(linux_kernel)] use crate::process::{Cpuid, MembarrierCommand, MembarrierQuery}; -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -use crate::process::{RawPid, Signal, WaitOptions, WaitStatus}; +#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] +use crate::process::{RawPid, WaitOptions, WaitStatus}; #[cfg(not(any( target_os = "espidf", target_os = "fuchsia", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] use crate::process::{Resource, Rlimit}; @@ -53,6 +62,7 @@ use crate::process::{Resource, Rlimit}; target_os = "espidf", target_os = "redox", target_os = "openbsd", + target_os = "vita", target_os = "wasi" )))] use crate::process::{WaitId, WaitidOptions, WaitidStatus}; @@ -209,7 +219,7 @@ pub(crate) fn umask(mask: Mode) -> Mode { unsafe { Mode::from_bits_retain(c::umask(mask.bits() as c::mode_t).into()) } } -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] +#[cfg(not(any(target_os = "fuchsia", target_os = "vita", target_os = "wasi")))] #[inline] pub(crate) fn nice(inc: i32) -> io::Result<i32> { libc_errno::set_errno(libc_errno::Errno(0)); @@ -221,7 +231,12 @@ pub(crate) fn nice(inc: i32) -> io::Result<i32> { } } -#[cfg(not(any(target_os = "espidf", target_os = "fuchsia", target_os = "wasi")))] +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "vita", + target_os = "wasi" +)))] #[inline] pub(crate) fn getpriority_user(uid: Uid) -> io::Result<i32> { libc_errno::set_errno(libc_errno::Errno(0)); @@ -233,7 +248,12 @@ pub(crate) fn getpriority_user(uid: Uid) -> io::Result<i32> { } } -#[cfg(not(any(target_os = "espidf", target_os = "fuchsia", target_os = "wasi")))] +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "vita", + target_os = "wasi" +)))] #[inline] pub(crate) fn getpriority_pgrp(pgid: Option<Pid>) -> io::Result<i32> { libc_errno::set_errno(libc_errno::Errno(0)); @@ -245,7 +265,12 @@ pub(crate) fn getpriority_pgrp(pgid: Option<Pid>) -> io::Result<i32> { } } -#[cfg(not(any(target_os = "espidf", target_os = "fuchsia", target_os = "wasi")))] +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "vita", + target_os = "wasi" +)))] #[inline] pub(crate) fn getpriority_process(pid: Option<Pid>) -> io::Result<i32> { libc_errno::set_errno(libc_errno::Errno(0)); @@ -257,13 +282,23 @@ pub(crate) fn getpriority_process(pid: Option<Pid>) -> io::Result<i32> { } } -#[cfg(not(any(target_os = "espidf", target_os = "fuchsia", target_os = "wasi")))] +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "vita", + target_os = "wasi" +)))] #[inline] pub(crate) fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> { unsafe { ret(c::setpriority(c::PRIO_USER, uid.as_raw() as _, priority)) } } -#[cfg(not(any(target_os = "espidf", target_os = "fuchsia", target_os = "wasi")))] +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "vita", + target_os = "wasi" +)))] #[inline] pub(crate) fn setpriority_pgrp(pgid: Option<Pid>, priority: i32) -> io::Result<()> { unsafe { @@ -275,7 +310,12 @@ pub(crate) fn setpriority_pgrp(pgid: Option<Pid>, priority: i32) -> io::Result<( } } -#[cfg(not(any(target_os = "espidf", target_os = "fuchsia", target_os = "wasi")))] +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "vita", + target_os = "wasi" +)))] #[inline] pub(crate) fn setpriority_process(pid: Option<Pid>, priority: i32) -> io::Result<()> { unsafe { @@ -291,6 +331,7 @@ pub(crate) fn setpriority_process(pid: Option<Pid>, priority: i32) -> io::Result target_os = "espidf", target_os = "fuchsia", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] #[inline] @@ -306,6 +347,7 @@ pub(crate) fn getrlimit(limit: Resource) -> Rlimit { target_os = "espidf", target_os = "fuchsia", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] #[inline] @@ -335,6 +377,7 @@ pub(crate) fn prlimit(pid: Option<Pid>, limit: Resource, new: Rlimit) -> io::Res target_os = "espidf", target_os = "fuchsia", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] fn rlimit_from_libc(lim: c::rlimit) -> Rlimit { @@ -356,6 +399,7 @@ fn rlimit_from_libc(lim: c::rlimit) -> Rlimit { target_os = "espidf", target_os = "fuchsia", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] fn rlimit_to_libc(lim: Rlimit) -> io::Result<c::rlimit> { @@ -371,13 +415,13 @@ fn rlimit_to_libc(lim: Rlimit) -> io::Result<c::rlimit> { Ok(c::rlimit { rlim_cur, rlim_max }) } -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] +#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] #[inline] pub(crate) fn wait(waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> { _waitpid(!0, waitopts) } -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] +#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] #[inline] pub(crate) fn waitpid( pid: Option<Pid>, @@ -386,7 +430,13 @@ pub(crate) fn waitpid( _waitpid(Pid::as_raw(pid), waitopts) } -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] +#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] +#[inline] +pub(crate) fn waitpgid(pgid: Pid, waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> { + _waitpid(-pgid.as_raw_nonzero().get(), waitopts) +} + +#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] #[inline] pub(crate) fn _waitpid( pid: RawPid, @@ -403,6 +453,7 @@ pub(crate) fn _waitpid( target_os = "espidf", target_os = "redox", target_os = "openbsd", + target_os = "vita", target_os = "wasi" )))] #[inline] @@ -411,6 +462,7 @@ pub(crate) fn waitid(id: WaitId<'_>, options: WaitidOptions) -> io::Result<Optio match id { WaitId::All => _waitid_all(options), WaitId::Pid(pid) => _waitid_pid(pid, options), + WaitId::Pgid(pgid) => _waitid_pgid(pgid, options), #[cfg(target_os = "linux")] WaitId::PidFd(fd) => _waitid_pidfd(fd, options), #[cfg(not(target_os = "linux"))] @@ -422,6 +474,7 @@ pub(crate) fn waitid(id: WaitId<'_>, options: WaitidOptions) -> io::Result<Optio target_os = "espidf", target_os = "redox", target_os = "openbsd", + target_os = "vita", target_os = "wasi" )))] #[inline] @@ -445,6 +498,7 @@ fn _waitid_all(options: WaitidOptions) -> io::Result<Option<WaitidStatus>> { target_os = "espidf", target_os = "redox", target_os = "openbsd", + target_os = "vita", target_os = "wasi" )))] #[inline] @@ -464,6 +518,30 @@ fn _waitid_pid(pid: Pid, options: WaitidOptions) -> io::Result<Option<WaitidStat Ok(unsafe { cvt_waitid_status(status) }) } +#[cfg(not(any( + target_os = "espidf", + target_os = "redox", + target_os = "openbsd", + target_os = "vita", + target_os = "wasi" +)))] +#[inline] +fn _waitid_pgid(pgid: Option<Pid>, options: WaitidOptions) -> io::Result<Option<WaitidStatus>> { + // `waitid` can return successfully without initializing the struct (no + // children found when using `WNOHANG`) + let mut status = MaybeUninit::<c::siginfo_t>::zeroed(); + unsafe { + ret(c::waitid( + c::P_PGID, + Pid::as_raw(pgid) as _, + status.as_mut_ptr(), + options.bits() as _, + ))? + }; + + Ok(unsafe { cvt_waitid_status(status) }) +} + #[cfg(target_os = "linux")] #[inline] fn _waitid_pidfd(fd: BorrowedFd<'_>, options: WaitidOptions) -> io::Result<Option<WaitidStatus>> { @@ -492,6 +570,7 @@ fn _waitid_pidfd(fd: BorrowedFd<'_>, options: WaitidOptions) -> io::Result<Optio target_os = "espidf", target_os = "openbsd", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] #[inline] diff --git a/vendor/rustix/src/backend/libc/process/types.rs b/vendor/rustix/src/backend/libc/process/types.rs index 26bae3498..8689c414a 100644 --- a/vendor/rustix/src/backend/libc/process/types.rs +++ b/vendor/rustix/src/backend/libc/process/types.rs @@ -1,3 +1,4 @@ +#[cfg(not(any(target_os = "espidf", target_os = "vita")))] use crate::backend::c; /// A command for use with [`membarrier`] and [`membarrier_cpu`]. @@ -44,6 +45,7 @@ pub enum MembarrierCommand { target_os = "espidf", target_os = "fuchsia", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] #[derive(Copy, Clone, Debug, Eq, PartialEq)] @@ -82,6 +84,7 @@ pub enum Resource { solarish, target_os = "aix", target_os = "haiku", + target_os = "hurd", target_os = "nto" )))] Locks = bitcast!(c::RLIMIT_LOCKS), @@ -91,6 +94,7 @@ pub enum Resource { solarish, target_os = "aix", target_os = "haiku", + target_os = "hurd", target_os = "nto" )))] Sigpending = bitcast!(c::RLIMIT_SIGPENDING), @@ -100,6 +104,7 @@ pub enum Resource { solarish, target_os = "aix", target_os = "haiku", + target_os = "hurd", target_os = "nto" )))] Msgqueue = bitcast!(c::RLIMIT_MSGQUEUE), @@ -109,6 +114,7 @@ pub enum Resource { solarish, target_os = "aix", target_os = "haiku", + target_os = "hurd", target_os = "nto" )))] Nice = bitcast!(c::RLIMIT_NICE), @@ -118,6 +124,7 @@ pub enum Resource { solarish, target_os = "aix", target_os = "haiku", + target_os = "hurd", target_os = "nto" )))] Rtprio = bitcast!(c::RLIMIT_RTPRIO), @@ -129,6 +136,7 @@ pub enum Resource { target_os = "android", target_os = "emscripten", target_os = "haiku", + target_os = "hurd", target_os = "nto", )))] Rttime = bitcast!(c::RLIMIT_RTTIME), diff --git a/vendor/rustix/src/backend/libc/pty/syscalls.rs b/vendor/rustix/src/backend/libc/pty/syscalls.rs index cf566045d..86f3a6c46 100644 --- a/vendor/rustix/src/backend/libc/pty/syscalls.rs +++ b/vendor/rustix/src/backend/libc/pty/syscalls.rs @@ -67,7 +67,8 @@ pub(crate) fn ptsname(fd: BorrowedFd<'_>, mut buffer: Vec<u8>) -> io::Result<CSt 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. + // The size declared in the `TIOCPTYGNAME` macro in + // sys/ttycom.h is 128. let mut name: [u8; 128] = [0_u8; 128]; match c::ioctl(borrowed_fd(fd), c::TIOCPTYGNAME as _, &mut name) { 0 => { @@ -87,7 +88,8 @@ pub(crate) fn ptsname(fd: BorrowedFd<'_>, mut buffer: Vec<u8>) -> io::Result<CSt return Err(io::Errno::from_raw_os_error(r)); } - buffer.reserve(1); // use `Vec` reallocation strategy to grow capacity exponentially + // Use `Vec` reallocation strategy to grow capacity exponentially. + buffer.reserve(1); buffer.resize(buffer.capacity(), 0_u8); } } diff --git a/vendor/rustix/src/backend/libc/rand/types.rs b/vendor/rustix/src/backend/libc/rand/types.rs index cd436b618..46690b57f 100644 --- a/vendor/rustix/src/backend/libc/rand/types.rs +++ b/vendor/rustix/src/backend/libc/rand/types.rs @@ -18,7 +18,7 @@ bitflags! { /// `GRND_INSECURE` const INSECURE = c::GRND_INSECURE; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/libc/shm/mod.rs b/vendor/rustix/src/backend/libc/shm/mod.rs new file mode 100644 index 000000000..1e0181a99 --- /dev/null +++ b/vendor/rustix/src/backend/libc/shm/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/shm/syscalls.rs b/vendor/rustix/src/backend/libc/shm/syscalls.rs new file mode 100644 index 000000000..b0d907ff2 --- /dev/null +++ b/vendor/rustix/src/backend/libc/shm/syscalls.rs @@ -0,0 +1,25 @@ +use crate::ffi::CStr; + +use crate::backend::c; +use crate::backend::conv::{c_str, ret, ret_owned_fd}; +use crate::fd::OwnedFd; +use crate::fs::Mode; +use crate::io; +use crate::shm::ShmOFlags; + +pub(crate) fn shm_open(name: &CStr, oflags: ShmOFlags, mode: Mode) -> io::Result<OwnedFd> { + // On this platforms, `mode_t` is `u16` and can't be passed directly to a + // variadic function. + #[cfg(apple)] + let mode: c::c_uint = mode.bits().into(); + + // Otherwise, cast to `mode_t` as that's what `open` is documented to take. + #[cfg(not(apple))] + let mode: c::mode_t = mode.bits() as _; + + unsafe { ret_owned_fd(c::shm_open(c_str(name), bitflags_bits!(oflags), mode)) } +} + +pub(crate) fn shm_unlink(name: &CStr) -> io::Result<()> { + unsafe { ret(c::shm_unlink(c_str(name))) } +} diff --git a/vendor/rustix/src/backend/libc/shm/types.rs b/vendor/rustix/src/backend/libc/shm/types.rs new file mode 100644 index 000000000..6575ef523 --- /dev/null +++ b/vendor/rustix/src/backend/libc/shm/types.rs @@ -0,0 +1,30 @@ +use crate::backend::c; +use bitflags::bitflags; + +bitflags! { + /// `O_*` constants for use with [`shm_open`]. + /// + /// [`shm_open`]: crate:shm::shm_open + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct ShmOFlags: u32 { + /// `O_CREAT` + #[doc(alias = "CREAT")] + const CREATE = bitcast!(c::O_CREAT); + + /// `O_EXCL` + const EXCL = bitcast!(c::O_EXCL); + + /// `O_RDONLY` + const RDONLY = bitcast!(c::O_RDONLY); + + /// `O_RDWR` + const RDWR = bitcast!(c::O_RDWR); + + /// `O_TRUNC` + const TRUNC = bitcast!(c::O_TRUNC); + + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> + const _ = !0; + } +} diff --git a/vendor/rustix/src/backend/libc/system/syscalls.rs b/vendor/rustix/src/backend/libc/system/syscalls.rs index 27efd2653..05d674b2c 100644 --- a/vendor/rustix/src/backend/libc/system/syscalls.rs +++ b/vendor/rustix/src/backend/libc/system/syscalls.rs @@ -4,6 +4,8 @@ use super::types::RawUname; use crate::backend::c; #[cfg(not(target_os = "wasi"))] use crate::backend::conv::ret_infallible; +#[cfg(target_os = "linux")] +use crate::system::RebootCommand; #[cfg(linux_kernel)] use crate::system::Sysinfo; use core::mem::MaybeUninit; @@ -11,6 +13,7 @@ use core::mem::MaybeUninit; target_os = "emscripten", target_os = "espidf", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] use {crate::backend::conv::ret, crate::io}; @@ -46,6 +49,7 @@ pub(crate) fn sysinfo() -> Sysinfo { target_os = "emscripten", target_os = "espidf", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] pub(crate) fn sethostname(name: &[u8]) -> io::Result<()> { @@ -56,3 +60,8 @@ pub(crate) fn sethostname(name: &[u8]) -> io::Result<()> { )) } } + +#[cfg(target_os = "linux")] +pub(crate) fn reboot(cmd: RebootCommand) -> io::Result<()> { + unsafe { ret(c::reboot(cmd as i32)) } +} diff --git a/vendor/rustix/src/backend/libc/termios/syscalls.rs b/vendor/rustix/src/backend/libc/termios/syscalls.rs index df96595cd..35d4e2349 100644 --- a/vendor/rustix/src/backend/libc/termios/syscalls.rs +++ b/vendor/rustix/src/backend/libc/termios/syscalls.rs @@ -40,6 +40,13 @@ pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result<Termios> { let termios2 = unsafe { let mut termios2 = MaybeUninit::<c::termios2>::uninit(); + // QEMU's `TCGETS2` doesn't currently set `input_speed` or + // `output_speed` on PowerPC, so zero out the fields ourselves. + #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] + { + termios2.write(core::mem::zeroed()); + } + ret(c::ioctl( borrowed_fd(fd), c::TCGETS2 as _, @@ -60,6 +67,33 @@ pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result<Termios> { input_speed: termios2.c_ispeed, output_speed: termios2.c_ospeed, }; + + // QEMU's `TCGETS2` doesn't currently set `input_speed` or + // `output_speed` on PowerPC, so set them manually if we can. + #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] + { + use crate::termios::speed; + + if result.output_speed == 0 && (termios2.c_cflag & c::CBAUD) != c::BOTHER { + if let Some(output_speed) = speed::decode(termios2.c_cflag & c::CBAUD) { + result.output_speed = output_speed; + } + } + if result.input_speed == 0 + && ((termios2.c_cflag & c::CIBAUD) >> c::IBSHIFT) != c::BOTHER + { + // For input speeds, `B0` is special-cased to mean the input + // speed is the same as the output speed. + if ((termios2.c_cflag & c::CIBAUD) >> c::IBSHIFT) == c::B0 { + result.input_speed = result.output_speed; + } else if let Some(input_speed) = + speed::decode((termios2.c_cflag & c::CIBAUD) >> c::IBSHIFT) + { + result.input_speed = input_speed; + } + } + } + result.special_codes.0[..termios2.c_cc.len()].copy_from_slice(&termios2.c_cc); Ok(result) @@ -110,12 +144,12 @@ pub(crate) fn tcsetattr( // 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; + const TCSETS: u32 = 0x8024_5409; #[cfg(any(target_arch = "sparc", target_arch = "sparc64"))] - const TCSETS2: u32 = 0x802c540d; + const TCSETS2: u32 = 0x802c_540d; - // Translate from `optional_actions` into an ioctl request code. On MIPS, - // `optional_actions` already has `TCGETS` added to it. + // 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", @@ -341,7 +375,7 @@ pub(crate) fn cfmakeraw(termios: &mut Termios) { pub(crate) fn isatty(fd: BorrowedFd<'_>) -> bool { // Use the return value of `isatty` alone. We don't check `errno` because // we return `bool` rather than `io::Result<bool>`, because we assume - // `BorrrowedFd` protects us from `EBADF`, and any other reasonably + // `BorrowedFd` protects us from `EBADF`, and any other reasonably // anticipated `errno` value would end up interpreted as “assume it's not a // terminal” anyway. unsafe { c::isatty(borrowed_fd(fd)) != 0 } diff --git a/vendor/rustix/src/backend/libc/thread/syscalls.rs b/vendor/rustix/src/backend/libc/thread/syscalls.rs index 846f0e2a8..33750f405 100644 --- a/vendor/rustix/src/backend/libc/thread/syscalls.rs +++ b/vendor/rustix/src/backend/libc/thread/syscalls.rs @@ -24,6 +24,7 @@ use { target_os = "haiku", target_os = "openbsd", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] use {crate::thread::ClockId, core::ptr::null_mut}; @@ -42,6 +43,7 @@ weak!(fn __nanosleep64(*const LibcTimespec, *mut LibcTimespec) -> c::c_int); target_os = "haiku", target_os = "openbsd", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] #[inline] @@ -92,7 +94,12 @@ pub(crate) fn clock_nanosleep_relative(id: ClockId, request: &Timespec) -> Nanos #[cfg(all( fix_y2038, - not(any(apple, target_os = "emscripten", target_os = "haiku")) + not(any( + apple, + target_os = "emscripten", + target_os = "haiku", + target_os = "vita" + )) ))] fn clock_nanosleep_relative_old(id: ClockId, request: &Timespec) -> NanosleepRelativeResult { let tv_sec = match request.tv_sec.try_into() { @@ -137,6 +144,7 @@ fn clock_nanosleep_relative_old(id: ClockId, request: &Timespec) -> NanosleepRel target_os = "haiku", target_os = "openbsd", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] #[inline] @@ -180,7 +188,12 @@ pub(crate) fn clock_nanosleep_absolute(id: ClockId, request: &Timespec) -> io::R #[cfg(all( fix_y2038, - not(any(apple, target_os = "emscripten", target_os = "haiku")) + not(any( + apple, + target_os = "emscripten", + target_os = "haiku", + target_os = "vita" + )) ))] fn clock_nanosleep_absolute_old(id: ClockId, request: &Timespec) -> io::Result<()> { let flags = c::TIMER_ABSTIME; diff --git a/vendor/rustix/src/backend/libc/time/types.rs b/vendor/rustix/src/backend/libc/time/types.rs index 4d8c6bdab..1514b02d0 100644 --- a/vendor/rustix/src/backend/libc/time/types.rs +++ b/vendor/rustix/src/backend/libc/time/types.rs @@ -88,7 +88,7 @@ bitflags! { /// `TFD_CLOEXEC` const CLOEXEC = bitcast!(c::TFD_CLOEXEC); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -108,7 +108,7 @@ bitflags! { #[cfg(linux_kernel)] const CANCEL_ON_SET = bitcast!(c::TFD_TIMER_CANCEL_ON_SET); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/c.rs b/vendor/rustix/src/backend/linux_raw/c.rs index 65ddb1466..01c5eafb1 100644 --- a/vendor/rustix/src/backend/linux_raw/c.rs +++ b/vendor/rustix/src/backend/linux_raw/c.rs @@ -6,7 +6,7 @@ #![allow(unused_imports)] #![allow(non_camel_case_types)] -pub type size_t = usize; +pub(crate) type size_t = usize; pub(crate) use linux_raw_sys::ctypes::*; pub(crate) use linux_raw_sys::errno::EINVAL; pub(crate) use linux_raw_sys::ioctl::{FIONBIO, FIONREAD}; @@ -51,31 +51,88 @@ pub(crate) use linux_raw_sys::{ general::{O_CLOEXEC as SOCK_CLOEXEC, O_NONBLOCK as SOCK_NONBLOCK}, if_ether::*, net::{ - AF_DECnet, __kernel_sa_family_t as sa_family_t, - __kernel_sockaddr_storage as sockaddr_storage, cmsghdr, in6_addr, in_addr, ip_mreq, - ipv6_mreq, linger, msghdr, sockaddr, sockaddr_in, sockaddr_in6, sockaddr_un, socklen_t, - AF_APPLETALK, AF_ASH, AF_ATMPVC, AF_ATMSVC, AF_AX25, AF_BLUETOOTH, AF_BRIDGE, AF_CAN, - AF_ECONET, AF_IEEE802154, AF_INET, AF_INET6, AF_IPX, AF_IRDA, AF_ISDN, AF_IUCV, AF_KEY, - AF_LLC, AF_NETBEUI, AF_NETLINK, AF_NETROM, AF_PACKET, AF_PHONET, AF_PPPOX, AF_RDS, AF_ROSE, - AF_RXRPC, AF_SECURITY, AF_SNA, AF_TIPC, AF_UNIX, AF_UNSPEC, AF_WANPIPE, AF_X25, IPPROTO_AH, - IPPROTO_BEETPH, IPPROTO_COMP, IPPROTO_DCCP, IPPROTO_EGP, IPPROTO_ENCAP, IPPROTO_ESP, - IPPROTO_ETHERNET, IPPROTO_FRAGMENT, IPPROTO_GRE, IPPROTO_ICMP, IPPROTO_ICMPV6, IPPROTO_IDP, - IPPROTO_IGMP, IPPROTO_IP, IPPROTO_IPIP, IPPROTO_IPV6, IPPROTO_MH, IPPROTO_MPLS, - IPPROTO_MPTCP, IPPROTO_MTP, IPPROTO_PIM, IPPROTO_PUP, IPPROTO_RAW, IPPROTO_ROUTING, - IPPROTO_RSVP, IPPROTO_SCTP, IPPROTO_TCP, IPPROTO_TP, IPPROTO_UDP, IPPROTO_UDPLITE, - IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_MULTICAST_HOPS, IPV6_MULTICAST_LOOP, - IPV6_UNICAST_HOPS, IPV6_V6ONLY, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP, IP_MULTICAST_LOOP, - IP_MULTICAST_TTL, IP_TTL, MSG_CMSG_CLOEXEC, MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, - MSG_EOR, MSG_ERRQUEUE, MSG_MORE, MSG_NOSIGNAL, MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL, - SCM_CREDENTIALS, SCM_RIGHTS, SHUT_RD, SHUT_RDWR, SHUT_WR, SOCK_DGRAM, SOCK_RAW, SOCK_RDM, - SOCK_SEQPACKET, SOCK_STREAM, SOL_SOCKET, SO_BROADCAST, SO_DOMAIN, SO_ERROR, SO_KEEPALIVE, - SO_LINGER, SO_PASSCRED, SO_RCVBUF, SO_RCVTIMEO_NEW, SO_RCVTIMEO_NEW as SO_RCVTIMEO, - SO_RCVTIMEO_OLD, SO_REUSEADDR, SO_SNDBUF, SO_SNDTIMEO_NEW, SO_SNDTIMEO_NEW as SO_SNDTIMEO, - SO_SNDTIMEO_OLD, SO_TYPE, TCP_NODELAY, + linger, msghdr, sockaddr, sockaddr_in, sockaddr_in6, sockaddr_un, socklen_t, AF_DECnet, + __kernel_sa_family_t as sa_family_t, __kernel_sockaddr_storage as sockaddr_storage, + cmsghdr, in6_addr, in_addr, ip_mreq, ip_mreq_source, ip_mreqn, ipv6_mreq, AF_APPLETALK, + AF_ASH, AF_ATMPVC, AF_ATMSVC, AF_AX25, AF_BLUETOOTH, AF_BRIDGE, AF_CAN, AF_ECONET, + AF_IEEE802154, AF_INET, AF_INET6, AF_IPX, AF_IRDA, AF_ISDN, AF_IUCV, AF_KEY, AF_LLC, + AF_NETBEUI, AF_NETLINK, AF_NETROM, AF_PACKET, AF_PHONET, AF_PPPOX, AF_RDS, AF_ROSE, + AF_RXRPC, AF_SECURITY, AF_SNA, AF_TIPC, AF_UNIX, AF_UNSPEC, AF_WANPIPE, AF_X25, + IP6T_SO_ORIGINAL_DST, IPPROTO_FRAGMENT, IPPROTO_ICMPV6, IPPROTO_MH, IPPROTO_ROUTING, + IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_FREEBIND, IPV6_MULTICAST_HOPS, + IPV6_MULTICAST_LOOP, IPV6_RECVTCLASS, IPV6_TCLASS, IPV6_UNICAST_HOPS, IPV6_V6ONLY, + IP_ADD_MEMBERSHIP, IP_ADD_SOURCE_MEMBERSHIP, IP_DROP_MEMBERSHIP, IP_DROP_SOURCE_MEMBERSHIP, + IP_FREEBIND, IP_MULTICAST_LOOP, IP_MULTICAST_TTL, IP_RECVTOS, IP_TOS, IP_TTL, + MSG_CMSG_CLOEXEC, MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, MSG_EOR, MSG_ERRQUEUE, + MSG_MORE, MSG_NOSIGNAL, MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL, SCM_CREDENTIALS, + SCM_RIGHTS, SHUT_RD, SHUT_RDWR, SHUT_WR, SOCK_DGRAM, SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, + SOCK_STREAM, SOL_SOCKET, SO_ACCEPTCONN, SO_BROADCAST, SO_COOKIE, SO_DOMAIN, SO_ERROR, + SO_INCOMING_CPU, SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE, SO_ORIGINAL_DST, SO_PASSCRED, + SO_PROTOCOL, SO_RCVBUF, SO_RCVTIMEO_NEW, SO_RCVTIMEO_NEW as SO_RCVTIMEO, SO_RCVTIMEO_OLD, + SO_REUSEADDR, SO_REUSEPORT, SO_SNDBUF, SO_SNDTIMEO_NEW, SO_SNDTIMEO_NEW as SO_SNDTIMEO, + SO_SNDTIMEO_OLD, SO_TYPE, TCP_CONGESTION, TCP_CORK, TCP_KEEPCNT, TCP_KEEPIDLE, + TCP_KEEPINTVL, TCP_NODELAY, TCP_QUICKACK, TCP_THIN_LINEAR_TIMEOUTS, TCP_USER_TIMEOUT, }, netlink::*, }; +// Cast away bindgen's `enum` type to make these consistent with the other +// `setsockopt`/`getsockopt` level values. +#[cfg(feature = "net")] +pub(crate) const IPPROTO_IP: u32 = linux_raw_sys::net::IPPROTO_IP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_ICMP: u32 = linux_raw_sys::net::IPPROTO_ICMP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_IGMP: u32 = linux_raw_sys::net::IPPROTO_IGMP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_IPIP: u32 = linux_raw_sys::net::IPPROTO_IPIP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_TCP: u32 = linux_raw_sys::net::IPPROTO_TCP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_EGP: u32 = linux_raw_sys::net::IPPROTO_EGP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_PUP: u32 = linux_raw_sys::net::IPPROTO_PUP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_UDP: u32 = linux_raw_sys::net::IPPROTO_UDP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_IDP: u32 = linux_raw_sys::net::IPPROTO_IDP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_TP: u32 = linux_raw_sys::net::IPPROTO_TP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_DCCP: u32 = linux_raw_sys::net::IPPROTO_DCCP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_IPV6: u32 = linux_raw_sys::net::IPPROTO_IPV6 as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_RSVP: u32 = linux_raw_sys::net::IPPROTO_RSVP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_GRE: u32 = linux_raw_sys::net::IPPROTO_GRE as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_ESP: u32 = linux_raw_sys::net::IPPROTO_ESP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_AH: u32 = linux_raw_sys::net::IPPROTO_AH as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_MTP: u32 = linux_raw_sys::net::IPPROTO_MTP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_BEETPH: u32 = linux_raw_sys::net::IPPROTO_BEETPH as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_ENCAP: u32 = linux_raw_sys::net::IPPROTO_ENCAP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_PIM: u32 = linux_raw_sys::net::IPPROTO_PIM as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_COMP: u32 = linux_raw_sys::net::IPPROTO_COMP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_SCTP: u32 = linux_raw_sys::net::IPPROTO_SCTP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_UDPLITE: u32 = linux_raw_sys::net::IPPROTO_UDPLITE as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_MPLS: u32 = linux_raw_sys::net::IPPROTO_MPLS as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_ETHERNET: u32 = linux_raw_sys::net::IPPROTO_ETHERNET as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_RAW: u32 = linux_raw_sys::net::IPPROTO_RAW as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_MPTCP: u32 = linux_raw_sys::net::IPPROTO_MPTCP as _; + #[cfg(any(feature = "process", feature = "runtime"))] pub(crate) use linux_raw_sys::general::siginfo_t; @@ -90,7 +147,7 @@ pub(crate) const EXIT_SIGNALED_SIGABRT: c_int = 128 + linux_raw_sys::general::SI pub(crate) use linux_raw_sys::{ general::{ CLD_CONTINUED, CLD_DUMPED, CLD_EXITED, CLD_KILLED, CLD_STOPPED, CLD_TRAPPED, - O_NONBLOCK as PIDFD_NONBLOCK, P_ALL, P_PID, P_PIDFD, + O_NONBLOCK as PIDFD_NONBLOCK, P_ALL, P_PGID, P_PID, P_PIDFD, }, ioctl::TIOCSCTTY, }; @@ -209,3 +266,28 @@ pub(crate) const CLOCK_THREAD_CPUTIME_ID: c_int = linux_raw_sys::general::CLOCK_THREAD_CPUTIME_ID as _; pub(crate) const CLOCK_PROCESS_CPUTIME_ID: c_int = linux_raw_sys::general::CLOCK_PROCESS_CPUTIME_ID as _; + +#[cfg(feature = "system")] +mod reboot_symbols { + use super::c_int; + + pub(crate) const LINUX_REBOOT_MAGIC1: c_int = linux_raw_sys::general::LINUX_REBOOT_MAGIC1 as _; + pub(crate) const LINUX_REBOOT_MAGIC2: c_int = linux_raw_sys::general::LINUX_REBOOT_MAGIC2 as _; + + pub(crate) const LINUX_REBOOT_CMD_RESTART: c_int = + linux_raw_sys::general::LINUX_REBOOT_CMD_RESTART as _; + pub(crate) const LINUX_REBOOT_CMD_HALT: c_int = + linux_raw_sys::general::LINUX_REBOOT_CMD_HALT as _; + pub(crate) const LINUX_REBOOT_CMD_CAD_ON: c_int = + linux_raw_sys::general::LINUX_REBOOT_CMD_CAD_ON as _; + pub(crate) const LINUX_REBOOT_CMD_CAD_OFF: c_int = + linux_raw_sys::general::LINUX_REBOOT_CMD_CAD_OFF as _; + pub(crate) const LINUX_REBOOT_CMD_POWER_OFF: c_int = + linux_raw_sys::general::LINUX_REBOOT_CMD_POWER_OFF as _; + pub(crate) const LINUX_REBOOT_CMD_SW_SUSPEND: c_int = + linux_raw_sys::general::LINUX_REBOOT_CMD_SW_SUSPEND as _; + pub(crate) const LINUX_REBOOT_CMD_KEXEC: c_int = + linux_raw_sys::general::LINUX_REBOOT_CMD_KEXEC as _; +} +#[cfg(feature = "system")] +pub(crate) use reboot_symbols::*; diff --git a/vendor/rustix/src/backend/linux_raw/conv.rs b/vendor/rustix/src/backend/linux_raw/conv.rs index f915db140..4b3c15d7a 100644 --- a/vendor/rustix/src/backend/linux_raw/conv.rs +++ b/vendor/rustix/src/backend/linux_raw/conv.rs @@ -2,8 +2,8 @@ //! //! System call arguments and return values are all communicated with inline //! asm and FFI as `*mut Opaque`. To protect these raw pointers from escaping -//! or being accidentally misused as they travel through the code, we wrap -//! them in [`ArgReg`] and [`RetReg`] structs. This file provides `From` +//! or being accidentally misused as they travel through the code, we wrap them +//! in [`ArgReg`] and [`RetReg`] structs. This file provides `From` //! implementations and explicit conversion functions for converting values //! into and out of these wrapper structs. //! @@ -581,7 +581,7 @@ impl<'a, Num: ArgNumber> From<crate::event::EventfdFlags> for ArgReg<'a, Num> { } } -#[cfg(all(feature = "alloc", feature = "event"))] +#[cfg(feature = "event")] impl<'a, Num: ArgNumber> From<crate::event::epoll::CreateFlags> for ArgReg<'a, Num> { #[inline] fn from(flags: crate::event::epoll::CreateFlags) -> Self { @@ -622,6 +622,15 @@ impl<'a, Num: ArgNumber> From<crate::backend::mm::types::MlockFlags> for ArgReg< } #[cfg(feature = "mm")] +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +impl<'a, Num: ArgNumber> From<crate::backend::mm::types::MlockAllFlags> for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::backend::mm::types::MlockAllFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "mm")] impl<'a, Num: ArgNumber> From<crate::backend::mm::types::MapFlags> for ArgReg<'a, Num> { #[inline] fn from(flags: crate::backend::mm::types::MapFlags) -> Self { diff --git a/vendor/rustix/src/backend/linux_raw/event/epoll.rs b/vendor/rustix/src/backend/linux_raw/event/epoll.rs index ecd48b784..6aa84d7aa 100644 --- a/vendor/rustix/src/backend/linux_raw/event/epoll.rs +++ b/vendor/rustix/src/backend/linux_raw/event/epoll.rs @@ -1,8 +1,4 @@ -//! epoll support. -//! -//! This is an experiment, and it isn't yet clear whether epoll is the right -//! level of abstraction at which to introduce safety. But it works fairly well -//! in simple examples 🙂. +//! Linx `epoll` support. //! //! # Examples //! @@ -79,6 +75,7 @@ use crate::backend::c; use crate::backend::event::syscalls; use crate::fd::{AsFd, AsRawFd, OwnedFd}; use crate::io; +#[cfg(feature = "alloc")] use alloc::vec::Vec; use bitflags::bitflags; use core::ffi::c_void; @@ -93,7 +90,7 @@ bitflags! { /// `EPOLL_CLOEXEC` const CLOEXEC = linux_raw_sys::general::EPOLL_CLOEXEC; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -148,7 +145,7 @@ bitflags! { /// `EPOLLEXCLUSIVE` const EXCLUSIVE = linux_raw_sys::general::EPOLLEXCLUSIVE as u32; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -242,6 +239,8 @@ pub fn delete(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. +#[cfg(feature = "alloc")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] #[inline] 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 @@ -288,8 +287,8 @@ pub struct Event { pub data: EventData, } -/// Data assocated with an [`Event`]. This can either be a 64-bit integer value -/// or a pointer which preserves pointer provenance. +/// Data associated 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 { @@ -371,10 +370,12 @@ struct SixtyFourBitPointer { } /// A vector of `Event`s, plus context for interpreting them. +#[cfg(feature = "alloc")] pub struct EventVec { events: Vec<Event>, } +#[cfg(feature = "alloc")] impl EventVec { /// Constructs an `EventVec` from raw pointer, length, and capacity. /// @@ -449,6 +450,7 @@ impl EventVec { } } +#[cfg(feature = "alloc")] impl<'a> IntoIterator for &'a EventVec { type IntoIter = Iter<'a>; type Item = Event; diff --git a/vendor/rustix/src/backend/linux_raw/event/mod.rs b/vendor/rustix/src/backend/linux_raw/event/mod.rs index 4148a8c7f..605de2538 100644 --- a/vendor/rustix/src/backend/linux_raw/event/mod.rs +++ b/vendor/rustix/src/backend/linux_raw/event/mod.rs @@ -1,4 +1,3 @@ -#[cfg(feature = "alloc")] pub mod epoll; pub(crate) mod poll_fd; pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/linux_raw/event/poll_fd.rs b/vendor/rustix/src/backend/linux_raw/event/poll_fd.rs index c56c9152d..51c222e62 100644 --- a/vendor/rustix/src/backend/linux_raw/event/poll_fd.rs +++ b/vendor/rustix/src/backend/linux_raw/event/poll_fd.rs @@ -31,7 +31,7 @@ bitflags! { /// `POLLRDHUP` const RDHUP = linux_raw_sys::general::POLLRDHUP as u16; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/event/syscalls.rs b/vendor/rustix/src/backend/linux_raw/event/syscalls.rs index a8003b004..6cb8d3d96 100644 --- a/vendor/rustix/src/backend/linux_raw/event/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/event/syscalls.rs @@ -6,17 +6,15 @@ #![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] use crate::backend::c; -use crate::backend::conv::{c_int, c_uint, ret_owned_fd, ret_usize, slice_mut}; -use crate::event::{EventfdFlags, PollFd}; -use crate::fd::OwnedFd; -use crate::io; #[cfg(feature = "alloc")] -use { - crate::backend::conv::{by_ref, pass_usize, raw_fd, ret, zero}, - crate::event::epoll, - crate::fd::BorrowedFd, - linux_raw_sys::general::{EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD}, +use crate::backend::conv::pass_usize; +use crate::backend::conv::{ + by_ref, c_int, c_uint, raw_fd, ret, ret_owned_fd, ret_usize, slice_mut, zero, }; +use crate::event::{epoll, EventfdFlags, PollFd}; +use crate::fd::{BorrowedFd, OwnedFd}; +use crate::io; +use linux_raw_sys::general::{EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD}; #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] use { crate::backend::conv::{opt_ref, size_of}, @@ -52,13 +50,11 @@ pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result<usiz } } -#[cfg(feature = "alloc")] #[inline] pub(crate) fn epoll_create(flags: epoll::CreateFlags) -> io::Result<OwnedFd> { unsafe { ret_owned_fd(syscall_readonly!(__NR_epoll_create1, flags)) } } -#[cfg(feature = "alloc")] #[inline] pub(crate) unsafe fn epoll_add( epfd: BorrowedFd<'_>, @@ -74,7 +70,6 @@ pub(crate) unsafe fn epoll_add( )) } -#[cfg(feature = "alloc")] #[inline] pub(crate) unsafe fn epoll_mod( epfd: BorrowedFd<'_>, @@ -90,7 +85,6 @@ pub(crate) unsafe fn epoll_mod( )) } -#[cfg(feature = "alloc")] #[inline] pub(crate) unsafe fn epoll_del(epfd: BorrowedFd<'_>, fd: c::c_int) -> io::Result<()> { ret(syscall_readonly!( diff --git a/vendor/rustix/src/backend/linux_raw/event/types.rs b/vendor/rustix/src/backend/linux_raw/event/types.rs index 3821f8f64..eb34bd0b3 100644 --- a/vendor/rustix/src/backend/linux_raw/event/types.rs +++ b/vendor/rustix/src/backend/linux_raw/event/types.rs @@ -15,7 +15,7 @@ bitflags! { /// `EFD_SEMAPHORE` const SEMAPHORE = linux_raw_sys::general::EFD_SEMAPHORE; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/fs/dir.rs b/vendor/rustix/src/backend/linux_raw/fs/dir.rs index 4df589af5..ea1017957 100644 --- a/vendor/rustix/src/backend/linux_raw/fs/dir.rs +++ b/vendor/rustix/src/backend/linux_raw/fs/dir.rs @@ -18,9 +18,17 @@ pub struct Dir { /// The `OwnedFd` that we read directory entries from. fd: OwnedFd, + /// Have we seen any errors in this iteration? + any_errors: bool, + + /// Should we rewind the stream on the next iteration? + rewind: bool, + + /// The buffer for `linux_dirent64` entries. buf: Vec<u8>, + + /// Where we are in the buffer. pos: usize, - next: Option<u64>, } impl Dir { @@ -38,25 +46,39 @@ impl Dir { Ok(Self { fd: fd_for_dir, + any_errors: false, + rewind: false, buf: Vec::new(), pos: 0, - next: None, }) } /// `rewinddir(self)` #[inline] pub fn rewind(&mut self) { + self.any_errors = false; + self.rewind = true; self.pos = self.buf.len(); - self.next = Some(0); } /// `readdir(self)`, where `None` means the end of the directory. pub fn read(&mut self) -> Option<io::Result<DirEntry>> { - if let Some(next) = self.next.take() { - match crate::backend::fs::syscalls::_seek(self.fd.as_fd(), next as i64, SEEK_SET) { + // If we've seen errors, don't continue to try to read anyting further. + if self.any_errors { + return None; + } + + // If a rewind was requested, seek to the beginning. + if self.rewind { + self.rewind = false; + match io::retry_on_intr(|| { + crate::backend::fs::syscalls::_seek(self.fd.as_fd(), 0, SEEK_SET) + }) { Ok(_) => (), - Err(err) => return Some(Err(err)), + Err(err) => { + self.any_errors = true; + return Some(Err(err)); + } } } @@ -78,7 +100,7 @@ impl Dir { if self.buf.len() - self.pos < size_of::<linux_dirent64>() { match self.read_more()? { Ok(()) => (), - Err(e) => return Some(Err(e)), + Err(err) => return Some(Err(err)), } } @@ -136,14 +158,31 @@ impl Dir { } fn read_more(&mut self) -> Option<io::Result<()>> { - let og_len = self.buf.len(); - // Capacity increment currently chosen by wild guess. - self.buf - .resize(self.buf.capacity() + 32 * size_of::<linux_dirent64>(), 0); - let nread = match crate::backend::fs::syscalls::getdents(self.fd.as_fd(), &mut self.buf) { + // The first few times we're called, we allocate a relatively small + // buffer, because many directories are small. If we're called more, + // use progressively larger allocations, up to a fixed maximum. + // + // The specific sizes and policy here have not been tuned in detail yet + // and may need to be adjusted. In doing so, we should be careful to + // avoid unbounded buffer growth. This buffer only exists to share the + // cost of a `getdents` call over many entries, so if it gets too big, + // cache and heap usage will outweigh the benefit. And ultimately, + // directories can contain more entries than we can allocate contiguous + // memory for, so we'll always need to cap the size at some point. + if self.buf.len() < 1024 * size_of::<linux_dirent64>() { + self.buf.reserve(32 * size_of::<linux_dirent64>()); + } + self.buf.resize(self.buf.capacity(), 0); + let nread = match io::retry_on_intr(|| { + crate::backend::fs::syscalls::getdents(self.fd.as_fd(), &mut self.buf) + }) { Ok(nread) => nread, + Err(io::Errno::NOENT) => { + self.any_errors = true; + return None; + } Err(err) => { - self.buf.resize(og_len, 0); + self.any_errors = true; return Some(Err(err)); } }; @@ -225,3 +264,33 @@ impl DirEntry { self.d_ino } } + +#[test] +fn dir_iterator_handles_io_errors() { + // create a dir, keep the FD, then delete the dir + let tmp = tempfile::tempdir().unwrap(); + let fd = crate::fs::openat( + crate::fs::CWD, + tmp.path(), + crate::fs::OFlags::RDONLY | crate::fs::OFlags::CLOEXEC, + crate::fs::Mode::empty(), + ) + .unwrap(); + + let file_fd = crate::fs::openat( + &fd, + tmp.path().join("test.txt"), + crate::fs::OFlags::WRONLY | crate::fs::OFlags::CREATE, + crate::fs::Mode::RWXU, + ) + .unwrap(); + + let mut dir = Dir::read_from(&fd).unwrap(); + + // Reach inside the `Dir` and replace its directory with a file, which + // will cause the subsequent `getdents64` to fail. + crate::io::dup2(&file_fd, &mut dir.fd).unwrap(); + + assert!(matches!(dir.next(), Some(Err(_)))); + assert!(matches!(dir.next(), None)); +} diff --git a/vendor/rustix/src/backend/linux_raw/fs/inotify.rs b/vendor/rustix/src/backend/linux_raw/fs/inotify.rs index ef205ffdf..aaba71d7c 100644 --- a/vendor/rustix/src/backend/linux_raw/fs/inotify.rs +++ b/vendor/rustix/src/backend/linux_raw/fs/inotify.rs @@ -18,7 +18,7 @@ bitflags! { /// `IN_NONBLOCK` const NONBLOCK = linux_raw_sys::general::IN_NONBLOCK; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -38,7 +38,7 @@ bitflags! { const CLOSE_NOWRITE = linux_raw_sys::general::IN_CLOSE_NOWRITE; /// `IN_CLOSE_WRITE` const CLOSE_WRITE = linux_raw_sys::general::IN_CLOSE_WRITE; - /// `IN_CREATE ` + /// `IN_CREATE` const CREATE = linux_raw_sys::general::IN_CREATE; /// `IN_DELETE` const DELETE = linux_raw_sys::general::IN_DELETE; @@ -75,7 +75,7 @@ bitflags! { /// `IN_ONLYDIR` const ONLYDIR = linux_raw_sys::general::IN_ONLYDIR; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -92,13 +92,12 @@ pub fn inotify_init(flags: CreateFlags) -> io::Result<OwnedFd> { /// `inotify_add_watch(self, path, flags)`—Adds a watch to inotify. /// -/// This registers or updates a watch for the filesystem path `path` -/// and returns a watch descriptor corresponding to this watch. +/// This registers or updates a watch for the filesystem path `path` and +/// returns a watch descriptor corresponding to this watch. /// -/// Note: Due to the existence of hardlinks, providing two -/// different paths to this method may result in it returning -/// the same watch descriptor. An application should keep track of this -/// externally to avoid logic errors. +/// Note: Due to the existence of hardlinks, providing two different paths to +/// this method may result in it returning the same watch descriptor. An +/// application should keep track of this externally to avoid logic errors. #[inline] pub fn inotify_add_watch<P: crate::path::Arg>( inot: BorrowedFd<'_>, diff --git a/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs b/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs index e72afb8ab..f856fa8b0 100644 --- a/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs @@ -378,6 +378,7 @@ pub(crate) fn fadvise(fd: BorrowedFd<'_>, pos: u64, len: u64, advice: Advice) -> lo(len) )) } + // On mips, the arguments are not reordered, and padding is inserted // instead to ensure alignment. #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] @@ -393,6 +394,9 @@ pub(crate) fn fadvise(fd: BorrowedFd<'_>, pos: u64, len: u64, advice: Advice) -> advice )) } + + // For all other 32-bit architectures, use `fadvise64_64` so that we get a + // 64-bit length. #[cfg(all( target_pointer_width = "32", not(any( @@ -413,6 +417,8 @@ pub(crate) fn fadvise(fd: BorrowedFd<'_>, pos: u64, len: u64, advice: Advice) -> advice )) } + + // On 64-bit architectures, use `fadvise64` which is sufficient. #[cfg(target_pointer_width = "64")] unsafe { ret(syscall_readonly!( @@ -951,7 +957,7 @@ pub(crate) fn readlink(path: &CStr, buf: &mut [u8]) -> io::Result<usize> { } } -#[cfg(feature = "alloc")] +#[cfg(any(feature = "alloc", all(linux_kernel, feature = "procfs")))] #[inline] pub(crate) fn readlinkat( dirfd: BorrowedFd<'_>, diff --git a/vendor/rustix/src/backend/linux_raw/fs/types.rs b/vendor/rustix/src/backend/linux_raw/fs/types.rs index 6e2e14f1e..85fe018a3 100644 --- a/vendor/rustix/src/backend/linux_raw/fs/types.rs +++ b/vendor/rustix/src/backend/linux_raw/fs/types.rs @@ -20,7 +20,7 @@ bitflags! { /// `F_OK` const EXISTS = linux_raw_sys::general::F_OK; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -61,7 +61,7 @@ bitflags! { /// `AT_STATX_DONT_SYNC` const STATX_DONT_SYNC = linux_raw_sys::general::AT_STATX_DONT_SYNC; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -120,7 +120,7 @@ bitflags! { /// `S_ISVTX` const SVTX = linux_raw_sys::general::S_ISVTX; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -179,9 +179,9 @@ bitflags! { /// Similar to `ACCMODE`, but just includes the read/write flags, and /// no other flags. /// - /// Some implementations include `O_PATH` in `O_ACCMODE`, when + /// On some platforms, `PATH` may be included in `ACCMODE`, when /// sometimes we really just want the read/write bits. Caution is - /// indicated, as the presence of `O_PATH` may mean that the read/write + /// indicated, as the presence of `PATH` may mean that the read/write /// bits don't have their usual meaning. const RWMODE = linux_raw_sys::general::O_RDONLY | linux_raw_sys::general::O_WRONLY | @@ -250,7 +250,7 @@ bitflags! { /// `O_DIRECT` const DIRECT = linux_raw_sys::general::O_DIRECT; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -280,7 +280,7 @@ bitflags! { /// `RESOLVE_CACHED` (since Linux 5.12) const CACHED = linux_raw_sys::general::RESOLVE_CACHED as u64; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -301,7 +301,7 @@ bitflags! { /// `RENAME_WHITEOUT` const WHITEOUT = linux_raw_sys::general::RENAME_WHITEOUT; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -453,7 +453,7 @@ bitflags! { /// `MFD_HUGE_16GB` const HUGE_16GB = linux_raw_sys::general::MFD_HUGE_16GB; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -478,7 +478,7 @@ bitflags! { /// `F_SEAL_FUTURE_WRITE` (since Linux 5.1) const FUTURE_WRITE = linux_raw_sys::general::F_SEAL_FUTURE_WRITE; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -538,7 +538,7 @@ bitflags! { /// `STATX_ALL` const ALL = linux_raw_sys::general::STATX_ALL; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -565,7 +565,7 @@ bitflags! { /// `FALLOC_FL_UNSHARE_RANGE` const UNSHARE_RANGE = linux_raw_sys::general::FALLOC_FL_UNSHARE_RANGE; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -602,7 +602,7 @@ bitflags! { /// `ST_SYNCHRONOUS` const SYNCHRONOUS = linux_raw_sys::general::MS_SYNCHRONOUS as u64; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/io/errno.rs b/vendor/rustix/src/backend/linux_raw/io/errno.rs index 7730a7237..8247faa1c 100644 --- a/vendor/rustix/src/backend/linux_raw/io/errno.rs +++ b/vendor/rustix/src/backend/linux_raw/io/errno.rs @@ -60,7 +60,7 @@ impl Errno { #[inline] pub fn from_io_error(io_err: &std::io::Error) -> Option<Self> { io_err.raw_os_error().and_then(|raw| { - // `std::io::Error` could theoretically have arbitrary "OS error" + // `std::io::Error` could theoretically have arbitrary OS error // values, so check that they're in Linux's range. if (1..4096).contains(&raw) { Some(Self::from_errno(raw as u32)) diff --git a/vendor/rustix/src/backend/linux_raw/io/syscalls.rs b/vendor/rustix/src/backend/linux_raw/io/syscalls.rs index d2cbba0c3..62c68a22f 100644 --- a/vendor/rustix/src/backend/linux_raw/io/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/io/syscalls.rs @@ -14,8 +14,8 @@ use crate::backend::conv::loff_t_from_u64; ))] use crate::backend::conv::zero; use crate::backend::conv::{ - c_uint, raw_fd, ret, ret_c_int, ret_c_uint, ret_discarded_fd, ret_owned_fd, ret_usize, slice, - slice_mut, + c_uint, pass_usize, raw_fd, ret, ret_c_int, ret_c_uint, ret_discarded_fd, ret_owned_fd, + ret_usize, slice, slice_mut, }; #[cfg(target_pointer_width = "32")] use crate::backend::conv::{hi, lo}; @@ -96,25 +96,16 @@ pub(crate) fn preadv( ) -> io::Result<usize> { let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]); - #[cfg(target_pointer_width = "32")] + // Unlike the plain "p" functions, the "pv" functions pass their offset in + // an endian-independent way, and always in two registers. unsafe { ret_usize(syscall!( __NR_preadv, fd, bufs_addr, bufs_len, - hi(pos), - lo(pos) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_usize(syscall!( - __NR_preadv, - fd, - bufs_addr, - bufs_len, - loff_t_from_u64(pos) + pass_usize(pos as usize), + pass_usize((pos >> 32) as usize) )) } } @@ -128,26 +119,16 @@ pub(crate) fn preadv2( ) -> io::Result<usize> { let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]); - #[cfg(target_pointer_width = "32")] - unsafe { - ret_usize(syscall!( - __NR_preadv2, - fd, - bufs_addr, - bufs_len, - hi(pos), - lo(pos), - flags - )) - } - #[cfg(target_pointer_width = "64")] + // Unlike the plain "p" functions, the "pv" functions pass their offset in + // an endian-independent way, and always in two registers. unsafe { ret_usize(syscall!( __NR_preadv2, fd, bufs_addr, bufs_len, - loff_t_from_u64(pos), + pass_usize(pos as usize), + pass_usize((pos >> 32) as usize), flags )) } @@ -217,25 +198,16 @@ pub(crate) fn writev(fd: BorrowedFd<'_>, bufs: &[IoSlice<'_>]) -> io::Result<usi pub(crate) fn pwritev(fd: BorrowedFd<'_>, bufs: &[IoSlice<'_>], pos: u64) -> io::Result<usize> { let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]); - #[cfg(target_pointer_width = "32")] + // Unlike the plain "p" functions, the "pv" functions pass their offset in + // an endian-independent way, and always in two registers. unsafe { ret_usize(syscall_readonly!( __NR_pwritev, fd, bufs_addr, bufs_len, - hi(pos), - lo(pos) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_usize(syscall_readonly!( - __NR_pwritev, - fd, - bufs_addr, - bufs_len, - loff_t_from_u64(pos) + pass_usize(pos as usize), + pass_usize((pos >> 32) as usize) )) } } @@ -249,26 +221,16 @@ pub(crate) fn pwritev2( ) -> io::Result<usize> { let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]); - #[cfg(target_pointer_width = "32")] - unsafe { - ret_usize(syscall_readonly!( - __NR_pwritev2, - fd, - bufs_addr, - bufs_len, - hi(pos), - lo(pos), - flags - )) - } - #[cfg(target_pointer_width = "64")] + // Unlike the plain "p" functions, the "pv" functions pass their offset in + // an endian-independent way, and always in two registers. unsafe { ret_usize(syscall_readonly!( __NR_pwritev2, fd, bufs_addr, bufs_len, - loff_t_from_u64(pos), + pass_usize(pos as usize), + pass_usize((pos >> 32) as usize), flags )) } diff --git a/vendor/rustix/src/backend/linux_raw/io/types.rs b/vendor/rustix/src/backend/linux_raw/io/types.rs index fb7e913a0..4b3dfc686 100644 --- a/vendor/rustix/src/backend/linux_raw/io/types.rs +++ b/vendor/rustix/src/backend/linux_raw/io/types.rs @@ -12,7 +12,7 @@ bitflags! { /// `FD_CLOEXEC` const CLOEXEC = linux_raw_sys::general::FD_CLOEXEC; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -36,7 +36,7 @@ bitflags! { /// `RWF_APPEND` (since Linux 4.16) const APPEND = linux_raw_sys::general::RWF_APPEND; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -51,7 +51,7 @@ bitflags! { /// `O_CLOEXEC` const CLOEXEC = linux_raw_sys::general::O_CLOEXEC; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs b/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs index b51f826a9..3d4274cfe 100644 --- a/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs @@ -6,6 +6,8 @@ #![allow(unsafe_code)] #![allow(clippy::undocumented_unsafe_blocks)] +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +use super::types::MlockAllFlags; use super::types::{ Advice, MapFlags, MlockFlags, MprotectFlags, MremapFlags, MsyncFlags, ProtFlags, UserfaultfdFlags, @@ -210,3 +212,30 @@ pub(crate) unsafe fn munlock(addr: *mut c::c_void, length: usize) -> io::Result< pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result<OwnedFd> { ret_owned_fd(syscall_readonly!(__NR_userfaultfd, flags)) } + +/// Locks all pages mapped into the address space of the calling process. +/// +/// This includes the pages of the code, data, and stack segment, as well as +/// shared libraries, user space kernel data, shared memory, and memory-mapped +/// files. All mapped pages are guaranteed to be resident in RAM when the call +/// returns successfully; the pages are guaranteed to stay in RAM until later +/// unlocked. +#[inline] +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +pub(crate) fn mlockall(flags: MlockAllFlags) -> io::Result<()> { + // When `mlockall` is used with `MCL_ONFAULT | MCL_FUTURE`, the ordering + // of `mlockall` with respect to arbitrary loads may be significant, + // because if a load happens and evokes a fault before the `mlockall`, + // the memory doesn't get locked, but if the load and therefore + // the fault happens after, then the memory does get locked. + // So to be conservative in this regard, we use `syscall` instead + // of `syscall_readonly` + unsafe { ret(syscall!(__NR_mlockall, flags)) } +} + +/// Unlocks all pages mapped into the address space of the calling process. +#[inline] +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +pub(crate) fn munlockall() -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_munlockall)) } +} diff --git a/vendor/rustix/src/backend/linux_raw/mm/types.rs b/vendor/rustix/src/backend/linux_raw/mm/types.rs index 0dfb41050..b5e36640d 100644 --- a/vendor/rustix/src/backend/linux_raw/mm/types.rs +++ b/vendor/rustix/src/backend/linux_raw/mm/types.rs @@ -17,7 +17,7 @@ bitflags! { /// `PROT_EXEC` const EXEC = linux_raw_sys::general::PROT_EXEC; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -56,7 +56,7 @@ bitflags! { #[cfg(any(target_arch = "sparc", target_arch = "sparc64"))] const ADI = linux_raw_sys::general::PROT_ADI; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -106,7 +106,7 @@ bitflags! { #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6", target_arch = "mips64", target_arch = "mips64r6")))] const UNINITIALIZED = linux_raw_sys::general::MAP_UNINITIALIZED; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -126,7 +126,7 @@ bitflags! { /// `MREMAP_DONTUNMAP` (since Linux 5.7) const DONTUNMAP = linux_raw_sys::general::MREMAP_DONTUNMAP; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -148,7 +148,7 @@ bitflags! { /// written). const INVALIDATE = linux_raw_sys::general::MS_INVALIDATE; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -163,7 +163,7 @@ bitflags! { /// `MLOCK_ONFAULT` const ONFAULT = linux_raw_sys::general::MLOCK_ONFAULT; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -240,9 +240,9 @@ pub enum Advice { impl Advice { /// `POSIX_MADV_DONTNEED` /// - /// On Linux, this is mapped to `POSIX_MADV_NORMAL` because - /// Linux's `MADV_DONTNEED` differs from `POSIX_MADV_DONTNEED`. See - /// `LinuxDontNeed` for the Linux behavior. + /// On Linux, this is mapped to `POSIX_MADV_NORMAL` because Linux's + /// `MADV_DONTNEED` differs from `POSIX_MADV_DONTNEED`. See `LinuxDontNeed` + /// for the Linux behavior. pub const DontNeed: Self = Self::Normal; } @@ -258,7 +258,39 @@ bitflags! { /// `O_NONBLOCK` const NONBLOCK = linux_raw_sys::general::O_NONBLOCK; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> + const _ = !0; + } +} + +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +bitflags! { + /// `MCL_*` flags for use with [`mlockall`]. + /// + /// [`mlockall`]: crate::mm::mlockall + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct MlockAllFlags: u32 { + /// Used together with `MCL_CURRENT`, `MCL_FUTURE`, or both. Mark all + /// current (with `MCL_CURRENT`) or future (with `MCL_FUTURE`) mappings + /// to lock pages when they are faulted in. When used with + /// `MCL_CURRENT`, all present pages are locked, but `mlockall` will + /// not fault in non-present pages. When used with `MCL_FUTURE`, all + /// future mappings will be marked to lock pages when they are faulted + /// in, but they will not be populated by the lock when the mapping is + /// created. `MCL_ONFAULT` must be used with either `MCL_CURRENT` or + /// `MCL_FUTURE` or both. + const ONFAULT = linux_raw_sys::general::MCL_ONFAULT; + /// Lock all pages which will become mapped into the address space of + /// the process in the future. These could be, for instance, new pages + /// required by a growing heap and stack as well as new memory-mapped + /// files or shared memory regions. + const FUTURE = linux_raw_sys::general::MCL_FUTURE; + /// Lock all pages which are currently mapped into the address space of + /// the process. + const CURRENT = linux_raw_sys::general::MCL_CURRENT; + + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/mod.rs b/vendor/rustix/src/backend/linux_raw/mod.rs index 9a07467f4..388f573dc 100644 --- a/vendor/rustix/src/backend/linux_raw/mod.rs +++ b/vendor/rustix/src/backend/linux_raw/mod.rs @@ -67,6 +67,8 @@ pub(crate) mod pty; pub(crate) mod rand; #[cfg(feature = "runtime")] pub(crate) mod runtime; +#[cfg(feature = "shm")] +pub(crate) mod shm; #[cfg(feature = "system")] pub(crate) mod system; #[cfg(feature = "termios")] diff --git a/vendor/rustix/src/backend/linux_raw/mount/types.rs b/vendor/rustix/src/backend/linux_raw/mount/types.rs index 221f8f315..3a797ab77 100644 --- a/vendor/rustix/src/backend/linux_raw/mount/types.rs +++ b/vendor/rustix/src/backend/linux_raw/mount/types.rs @@ -57,7 +57,7 @@ bitflags! { /// `MS_NOSYMFOLLOW` const NOSYMFOLLOW = linux_raw_sys::general::MS_NOSYMFOLLOW; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -78,7 +78,7 @@ bitflags! { /// `UMOUNT_NOFOLLOW` const NOFOLLOW = linux_raw_sys::general::UMOUNT_NOFOLLOW; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -94,7 +94,7 @@ bitflags! { /// `FSOPEN_CLOEXEC` const FSOPEN_CLOEXEC = linux_raw_sys::general::FSOPEN_CLOEXEC; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -110,7 +110,7 @@ bitflags! { /// `FSMOUNT_CLOEXEC` const FSMOUNT_CLOEXEC = linux_raw_sys::general::FSMOUNT_CLOEXEC; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -189,7 +189,7 @@ bitflags! { /// `MOUNT_ATTR__ATIME_FLAGS` const MOUNT_ATTR_SIZE_VER0 = linux_raw_sys::general::MOUNT_ATTR_SIZE_VER0; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -230,7 +230,7 @@ bitflags! { /// `MOVE_MOUNT__MASK` const MOVE_MOUNT__MASK = linux_raw_sys::general::MOVE_MOUNT__MASK; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -261,7 +261,7 @@ bitflags! { /// `AT_SYMLINK_NOFOLLOW` const AT_SYMLINK_NOFOLLOW = linux_raw_sys::general::AT_SYMLINK_NOFOLLOW; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -286,7 +286,7 @@ bitflags! { /// `FSPICK_EMPTY_PATH` const FSPICK_EMPTY_PATH = linux_raw_sys::general::FSPICK_EMPTY_PATH; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -311,7 +311,7 @@ bitflags! { /// `MS_REC` const REC = linux_raw_sys::general::MS_REC; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -323,7 +323,7 @@ bitflags! { const REMOUNT = linux_raw_sys::general::MS_REMOUNT; const MOVE = linux_raw_sys::general::MS_MOVE; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/net/mod.rs b/vendor/rustix/src/backend/linux_raw/net/mod.rs index 2b6ab34ba..f83c54621 100644 --- a/vendor/rustix/src/backend/linux_raw/net/mod.rs +++ b/vendor/rustix/src/backend/linux_raw/net/mod.rs @@ -2,5 +2,6 @@ pub(crate) mod addr; pub(crate) mod msghdr; pub(crate) mod read_sockaddr; pub(crate) mod send_recv; +pub(crate) mod sockopt; pub(crate) mod syscalls; pub(crate) mod write_sockaddr; diff --git a/vendor/rustix/src/backend/linux_raw/net/msghdr.rs b/vendor/rustix/src/backend/linux_raw/net/msghdr.rs index 659093920..2b88bfbbc 100644 --- a/vendor/rustix/src/backend/linux_raw/net/msghdr.rs +++ b/vendor/rustix/src/backend/linux_raw/net/msghdr.rs @@ -122,7 +122,7 @@ pub(crate) fn with_unix_msghdr<R>( f: impl FnOnce(c::msghdr) -> R, ) -> R { f(c::msghdr { - msg_name: as_ptr(addr) as _, + msg_name: as_ptr(&addr.unix) as _, msg_namelen: addr.addr_len() as _, msg_iov: iov.as_ptr() as _, msg_iovlen: msg_iov_len(iov.len()), diff --git a/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs b/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs index f4b7d9914..af7282c98 100644 --- a/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs +++ b/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs @@ -1,5 +1,5 @@ -//! 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. +//! 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. #![allow(unsafe_code)] use crate::backend::c; @@ -110,7 +110,7 @@ pub(crate) unsafe fn read_sockaddr( } } -/// Read a socket address returned from the OS. +/// Read an optional socket address returned from the OS. /// /// # Safety /// diff --git a/vendor/rustix/src/backend/linux_raw/net/send_recv.rs b/vendor/rustix/src/backend/linux_raw/net/send_recv.rs index 43b35341a..d5cdd075e 100644 --- a/vendor/rustix/src/backend/linux_raw/net/send_recv.rs +++ b/vendor/rustix/src/backend/linux_raw/net/send_recv.rs @@ -2,7 +2,8 @@ use crate::backend::c; use bitflags::bitflags; bitflags! { - /// `MSG_* flags for use with [`send`], [`send_to`], and related functions. + /// `MSG_*` flags for use with [`send`], [`send_to`], and related + /// functions. /// /// [`send`]: crate::net::send /// [`sendto`]: crate::net::sendto @@ -24,13 +25,14 @@ bitflags! { /// `MSG_OOB` const OOB = c::MSG_OOB; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } bitflags! { - /// `MSG_* flags for use with [`recv`], [`recvfrom`], and related functions. + /// `MSG_*` flags for use with [`recv`], [`recvfrom`], and related + /// functions. /// /// [`recv`]: crate::net::recv /// [`recvfrom`]: crate::net::recvfrom @@ -52,7 +54,7 @@ bitflags! { /// `MSG_WAITALL` const WAITALL = c::MSG_WAITALL; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/net/sockopt.rs b/vendor/rustix/src/backend/linux_raw/net/sockopt.rs new file mode 100644 index 000000000..6a740bbf7 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/net/sockopt.rs @@ -0,0 +1,879 @@ +//! linux_raw syscalls supporting `rustix::net::sockopt`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] + +use crate::backend::c; +use crate::backend::conv::{by_mut, c_uint, ret, socklen_t}; +use crate::fd::BorrowedFd; +#[cfg(feature = "alloc")] +use crate::ffi::CStr; +use crate::io; +use crate::net::sockopt::Timeout; +use crate::net::{ + AddressFamily, Ipv4Addr, Ipv6Addr, Protocol, RawProtocol, SocketAddrAny, SocketAddrStorage, + SocketAddrV4, SocketAddrV6, SocketType, UCred, +}; +#[cfg(feature = "alloc")] +use alloc::borrow::ToOwned; +#[cfg(feature = "alloc")] +use alloc::string::String; +use core::mem::MaybeUninit; +use core::time::Duration; +use linux_raw_sys::general::{__kernel_old_timeval, __kernel_sock_timeval}; +#[cfg(target_arch = "x86")] +use { + crate::backend::conv::{slice_just_addr, x86_sys}, + crate::backend::reg::{ArgReg, SocketArg}, + linux_raw_sys::net::{SYS_GETSOCKOPT, SYS_SETSOCKOPT}, +}; + +#[inline] +fn getsockopt<T: Copy>(fd: BorrowedFd<'_>, level: u32, optname: u32) -> io::Result<T> { + let mut optlen: c::socklen_t = core::mem::size_of::<T>().try_into().unwrap(); + debug_assert!( + optlen as usize >= core::mem::size_of::<c::c_int>(), + "Socket APIs don't ever use `bool` directly" + ); + + let mut value = MaybeUninit::<T>::uninit(); + getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; + + assert_eq!( + optlen as usize, + core::mem::size_of::<T>(), + "unexpected getsockopt size" + ); + + unsafe { Ok(value.assume_init()) } +} + +#[inline] +fn getsockopt_raw<T>( + fd: BorrowedFd<'_>, + level: u32, + optname: u32, + value: &mut MaybeUninit<T>, + optlen: &mut c::socklen_t, +) -> io::Result<()> { + #[cfg(not(target_arch = "x86"))] + unsafe { + ret(syscall!( + __NR_getsockopt, + fd, + c_uint(level), + c_uint(optname), + value, + by_mut(optlen) + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret(syscall!( + __NR_socketcall, + x86_sys(SYS_GETSOCKOPT), + slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ + fd.into(), + c_uint(level), + c_uint(optname), + value.into(), + by_mut(optlen), + ]) + )) + } +} + +#[inline] +fn setsockopt<T: Copy>(fd: BorrowedFd<'_>, level: u32, optname: u32, value: T) -> io::Result<()> { + let optlen = core::mem::size_of::<T>().try_into().unwrap(); + debug_assert!( + optlen as usize >= core::mem::size_of::<c::c_int>(), + "Socket APIs don't ever use `bool` directly" + ); + setsockopt_raw(fd, level, optname, &value, optlen) +} + +#[inline] +fn setsockopt_raw<T>( + fd: BorrowedFd<'_>, + level: u32, + optname: u32, + ptr: *const T, + optlen: c::socklen_t, +) -> io::Result<()> { + #[cfg(not(target_arch = "x86"))] + unsafe { + ret(syscall_readonly!( + __NR_setsockopt, + fd, + c_uint(level), + c_uint(optname), + ptr, + socklen_t(optlen) + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_SETSOCKOPT), + slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ + fd.into(), + c_uint(level), + c_uint(optname), + ptr.into(), + socklen_t(optlen), + ]) + )) + } +} + +#[inline] +pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result<SocketType> { + getsockopt(fd, c::SOL_SOCKET, c::SO_TYPE) +} + +#[inline] +pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR, from_bool(reuseaddr)) +} + +#[inline] +pub(crate) fn get_socket_reuseaddr(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST, from_bool(broadcast)) +} + +#[inline] +pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_linger(fd: BorrowedFd<'_>, linger: Option<Duration>) -> io::Result<()> { + // Convert `linger` to seconds, rounding up. + let l_linger = if let Some(linger) = linger { + duration_to_secs(linger)? + } else { + 0 + }; + let linger = c::linger { + l_onoff: c::c_int::from(linger.is_some()), + l_linger, + }; + setsockopt(fd, c::SOL_SOCKET, c::SO_LINGER, linger) +} + +#[inline] +pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result<Option<Duration>> { + let linger: c::linger = getsockopt(fd, c::SOL_SOCKET, c::SO_LINGER)?; + Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) +} + +#[inline] +pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED, from_bool(passcred)) +} + +#[inline] +pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_timeout( + fd: BorrowedFd<'_>, + id: Timeout, + timeout: Option<Duration>, +) -> io::Result<()> { + let time = duration_to_linux_sock_timeval(timeout)?; + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO_NEW, + Timeout::Send => c::SO_SNDTIMEO_NEW, + }; + match setsockopt(fd, c::SOL_SOCKET, optname, time) { + Err(io::Errno::NOPROTOOPT) if c::SO_RCVTIMEO_NEW != c::SO_RCVTIMEO_OLD => { + set_socket_timeout_old(fd, id, timeout) + } + otherwise => otherwise, + } +} + +/// Same as `set_socket_timeout` but uses `__kernel_old_timeval` instead of +/// `__kernel_sock_timeval` and `_OLD` constants instead of `_NEW`. +fn set_socket_timeout_old( + fd: BorrowedFd<'_>, + id: Timeout, + timeout: Option<Duration>, +) -> io::Result<()> { + let time = duration_to_linux_old_timeval(timeout)?; + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO_OLD, + Timeout::Send => c::SO_SNDTIMEO_OLD, + }; + setsockopt(fd, c::SOL_SOCKET, optname, time) +} + +#[inline] +pub(crate) fn get_socket_timeout(fd: BorrowedFd<'_>, id: Timeout) -> io::Result<Option<Duration>> { + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO_NEW, + Timeout::Send => c::SO_SNDTIMEO_NEW, + }; + let time: __kernel_sock_timeval = match getsockopt(fd, c::SOL_SOCKET, optname) { + Err(io::Errno::NOPROTOOPT) if c::SO_RCVTIMEO_NEW != c::SO_RCVTIMEO_OLD => { + return get_socket_timeout_old(fd, id) + } + otherwise => otherwise?, + }; + Ok(duration_from_linux_sock_timeval(time)) +} + +/// Same as `get_socket_timeout` but uses `__kernel_old_timeval` instead of +/// `__kernel_sock_timeval` and `_OLD` constants instead of `_NEW`. +fn get_socket_timeout_old(fd: BorrowedFd<'_>, id: Timeout) -> io::Result<Option<Duration>> { + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO_OLD, + Timeout::Send => c::SO_SNDTIMEO_OLD, + }; + let time: __kernel_old_timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; + Ok(duration_from_linux_old_timeval(time)) +} + +/// Convert a `__linux_sock_timeval` to a Rust `Option<Duration>`. +#[inline] +fn duration_from_linux_sock_timeval(time: __kernel_sock_timeval) -> Option<Duration> { + if time.tv_sec == 0 && time.tv_usec == 0 { + None + } else { + Some(Duration::from_secs(time.tv_sec as u64) + Duration::from_micros(time.tv_usec as u64)) + } +} + +/// Like `duration_from_linux` but uses Linux's old 32-bit +/// `__kernel_old_timeval`. +fn duration_from_linux_old_timeval(time: __kernel_old_timeval) -> Option<Duration> { + if time.tv_sec == 0 && time.tv_usec == 0 { + None + } else { + Some(Duration::from_secs(time.tv_sec as u64) + Duration::from_micros(time.tv_usec as u64)) + } +} + +/// Convert a Rust `Option<Duration>` to a `__kernel_sock_timeval`. +#[inline] +fn duration_to_linux_sock_timeval(timeout: Option<Duration>) -> io::Result<__kernel_sock_timeval> { + Ok(match timeout { + Some(timeout) => { + if timeout == Duration::ZERO { + return Err(io::Errno::INVAL); + } + // `subsec_micros` rounds down, so we use `subsec_nanos` and + // manually round up. + let mut timeout = __kernel_sock_timeval { + tv_sec: timeout.as_secs().try_into().unwrap_or(i64::MAX), + tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, + }; + if timeout.tv_sec == 0 && timeout.tv_usec == 0 { + timeout.tv_usec = 1; + } + timeout + } + None => __kernel_sock_timeval { + tv_sec: 0, + tv_usec: 0, + }, + }) +} + +/// Like `duration_to_linux` but uses Linux's old 32-bit +/// `__kernel_old_timeval`. +fn duration_to_linux_old_timeval(timeout: Option<Duration>) -> io::Result<__kernel_old_timeval> { + Ok(match timeout { + Some(timeout) => { + if timeout == Duration::ZERO { + return Err(io::Errno::INVAL); + } + + // `subsec_micros` rounds down, so we use `subsec_nanos` and + // manually round up. + let mut timeout = __kernel_old_timeval { + tv_sec: timeout.as_secs().try_into().unwrap_or(c::c_long::MAX), + tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, + }; + if timeout.tv_sec == 0 && timeout.tv_usec == 0 { + timeout.tv_usec = 1; + } + timeout + } + None => __kernel_old_timeval { + tv_sec: 0, + tv_usec: 0, + }, + }) +} + +#[inline] +pub(crate) fn get_socket_error(fd: BorrowedFd<'_>) -> io::Result<Result<(), io::Errno>> { + let err: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_ERROR)?; + Ok(if err == 0 { + Ok(()) + } else { + Err(io::Errno::from_raw_os_error(err)) + }) +} + +#[inline] +pub(crate) fn set_socket_keepalive(fd: BorrowedFd<'_>, keepalive: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE, from_bool(keepalive)) +} + +#[inline] +pub(crate) fn get_socket_keepalive(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { + let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; + setsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF, size) +} + +#[inline] +pub(crate) fn get_socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result<usize> { + getsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF).map(|size: u32| size as usize) +} + +#[inline] +pub(crate) fn set_socket_send_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { + let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; + setsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF, size) +} + +#[inline] +pub(crate) fn get_socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result<usize> { + getsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF).map(|size: u32| size as usize) +} + +#[inline] +pub(crate) fn get_socket_domain(fd: BorrowedFd<'_>) -> io::Result<AddressFamily> { + let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_DOMAIN)?; + Ok(AddressFamily( + domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?, + )) +} + +#[inline] +pub(crate) fn get_socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::SOL_SOCKET, c::SO_ACCEPTCONN).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_oobinline(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE, from_bool(value)) +} + +#[inline] +pub(crate) fn get_socket_oobinline(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_reuseport(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT, from_bool(value)) +} + +#[inline] +pub(crate) fn get_socket_reuseport(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT).map(to_bool) +} + +#[inline] +pub(crate) fn get_socket_protocol(fd: BorrowedFd<'_>) -> io::Result<Option<Protocol>> { + getsockopt(fd, c::SOL_SOCKET, c::SO_PROTOCOL) + .map(|raw: u32| RawProtocol::new(raw).map(Protocol::from_raw)) +} + +#[inline] +pub(crate) fn get_socket_cookie(fd: BorrowedFd<'_>) -> io::Result<u64> { + getsockopt(fd, c::SOL_SOCKET, c::SO_COOKIE) +} + +#[inline] +pub(crate) fn get_socket_incoming_cpu(fd: BorrowedFd<'_>) -> io::Result<u32> { + getsockopt(fd, c::SOL_SOCKET, c::SO_INCOMING_CPU) +} + +#[inline] +pub(crate) fn set_socket_incoming_cpu(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_INCOMING_CPU, value) +} + +#[inline] +pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IP_TTL, ttl) +} + +#[inline] +pub(crate) fn get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result<u32> { + getsockopt(fd, c::IPPROTO_IP, c::IP_TTL) +} + +#[inline] +pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY, from_bool(only_v6)) +} + +#[inline] +pub(crate) fn get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY).map(to_bool) +} + +#[inline] +pub(crate) fn set_ip_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IP, + c::IP_MULTICAST_LOOP, + from_bool(multicast_loop), + ) +} + +#[inline] +pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_LOOP).map(to_bool) +} + +#[inline] +pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl) +} + +#[inline] +pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result<u32> { + getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL) +} + +#[inline] +pub(crate) fn set_ipv6_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IPV6, + c::IPV6_MULTICAST_LOOP, + from_bool(multicast_loop), + ) +} + +#[inline] +pub(crate) fn get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP).map(to_bool) +} + +#[inline] +pub(crate) fn set_ipv6_multicast_hops(fd: BorrowedFd<'_>, multicast_hops: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS, multicast_hops) +} + +#[inline] +pub(crate) fn get_ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result<u32> { + getsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS) +} + +#[inline] +pub(crate) fn set_ip_add_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, +) -> io::Result<()> { + let mreq = to_ip_mreq(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn set_ip_add_membership_with_ifindex( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + address: &Ipv4Addr, + ifindex: i32, +) -> io::Result<()> { + let mreqn = to_ip_mreqn(multiaddr, address, ifindex); + setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreqn) +} + +#[inline] +pub(crate) fn set_ip_add_source_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> io::Result<()> { + let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); + setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_SOURCE_MEMBERSHIP, mreq_source) +} + +#[inline] +pub(crate) fn set_ip_drop_source_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> io::Result<()> { + let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); + setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_SOURCE_MEMBERSHIP, mreq_source) +} + +#[inline] +pub(crate) fn set_ipv6_add_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv6Addr, + interface: u32, +) -> io::Result<()> { + let mreq = to_ipv6mr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_ADD_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn set_ip_drop_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, +) -> io::Result<()> { + let mreq = to_ip_mreq(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn set_ip_drop_membership_with_ifindex( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + address: &Ipv4Addr, + ifindex: i32, +) -> io::Result<()> { + let mreqn = to_ip_mreqn(multiaddr, address, ifindex); + setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreqn) +} + +#[inline] +pub(crate) fn set_ipv6_drop_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv6Addr, + interface: u32, +) -> io::Result<()> { + let mreq = to_ipv6mr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_DROP_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn get_ipv6_unicast_hops(fd: BorrowedFd<'_>) -> io::Result<u8> { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) +} + +#[inline] +pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option<u8>) -> io::Result<()> { + let hops = match hops { + Some(hops) => hops.into(), + None => -1, + }; + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS, hops) +} + +#[inline] +pub(crate) fn set_ip_tos(fd: BorrowedFd<'_>, value: u8) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IP_TOS, i32::from(value)) +} + +#[inline] +pub(crate) fn get_ip_tos(fd: BorrowedFd<'_>) -> io::Result<u8> { + let value: i32 = getsockopt(fd, c::IPPROTO_IP, c::IP_TOS)?; + Ok(value as u8) +} + +#[inline] +pub(crate) fn set_ip_recvtos(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS, from_bool(value)) +} + +#[inline] +pub(crate) fn get_ip_recvtos(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS).map(to_bool) +} + +#[inline] +pub(crate) fn set_ipv6_recvtclass(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS, from_bool(value)) +} + +#[inline] +pub(crate) fn get_ipv6_recvtclass(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS).map(to_bool) +} + +#[inline] +pub(crate) fn set_ip_freebind(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IP_FREEBIND, from_bool(value)) +} + +#[inline] +pub(crate) fn get_ip_freebind(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_IP, c::IP_FREEBIND).map(to_bool) +} + +#[inline] +pub(crate) fn set_ipv6_freebind(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_FREEBIND, from_bool(value)) +} + +#[inline] +pub(crate) fn get_ipv6_freebind(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_FREEBIND).map(to_bool) +} + +#[inline] +pub(crate) fn get_ip_original_dst(fd: BorrowedFd<'_>) -> io::Result<SocketAddrV4> { + let level = c::IPPROTO_IP; + let optname = c::SO_ORIGINAL_DST; + let mut value = MaybeUninit::<SocketAddrStorage>::uninit(); + let mut optlen = core::mem::size_of_val(&value).try_into().unwrap(); + + getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; + + let any = unsafe { SocketAddrAny::read(value.as_ptr(), optlen as usize)? }; + match any { + SocketAddrAny::V4(v4) => Ok(v4), + _ => unreachable!(), + } +} + +#[inline] +pub(crate) fn get_ipv6_original_dst(fd: BorrowedFd<'_>) -> io::Result<SocketAddrV6> { + let level = c::IPPROTO_IPV6; + let optname = c::IP6T_SO_ORIGINAL_DST; + let mut value = MaybeUninit::<SocketAddrStorage>::uninit(); + let mut optlen = core::mem::size_of_val(&value).try_into().unwrap(); + + getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; + + let any = unsafe { SocketAddrAny::read(value.as_ptr(), optlen as usize)? }; + match any { + SocketAddrAny::V6(v6) => Ok(v6), + _ => unreachable!(), + } +} + +#[inline] +pub(crate) fn set_ipv6_tclass(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_TCLASS, value) +} + +#[inline] +pub(crate) fn get_ipv6_tclass(fd: BorrowedFd<'_>) -> io::Result<u32> { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_TCLASS) +} + +#[inline] +pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY, from_bool(nodelay)) +} + +#[inline] +pub(crate) fn get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY).map(to_bool) +} + +#[inline] +pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT, count) +} + +#[inline] +pub(crate) fn get_tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result<u32> { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT) +} + +#[inline] +pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { + let secs: c::c_uint = duration_to_secs(duration)?; + setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPIDLE, secs) +} + +#[inline] +pub(crate) fn get_tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result<Duration> { + let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPIDLE)?; + Ok(Duration::from_secs(secs as u64)) +} + +#[inline] +pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { + let secs: c::c_uint = duration_to_secs(duration)?; + setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL, secs) +} + +#[inline] +pub(crate) fn get_tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result<Duration> { + let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL)?; + Ok(Duration::from_secs(secs as u64)) +} + +#[inline] +pub(crate) fn set_tcp_user_timeout(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT, value) +} + +#[inline] +pub(crate) fn get_tcp_user_timeout(fd: BorrowedFd<'_>) -> io::Result<u32> { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT) +} + +#[inline] +pub(crate) fn set_tcp_quickack(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP, c::TCP_QUICKACK, from_bool(value)) +} + +#[inline] +pub(crate) fn get_tcp_quickack(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_QUICKACK).map(to_bool) +} + +#[inline] +pub(crate) fn set_tcp_congestion(fd: BorrowedFd<'_>, value: &str) -> io::Result<()> { + let level = c::IPPROTO_TCP; + let optname = c::TCP_CONGESTION; + let optlen = value.len().try_into().unwrap(); + setsockopt_raw(fd, level, optname, value.as_ptr(), optlen) +} + +#[cfg(feature = "alloc")] +#[inline] +pub(crate) fn get_tcp_congestion(fd: BorrowedFd<'_>) -> io::Result<String> { + let level = c::IPPROTO_TCP; + let optname = c::TCP_CONGESTION; + const OPTLEN: c::socklen_t = 16; + let mut value = MaybeUninit::<[MaybeUninit<u8>; OPTLEN as usize]>::uninit(); + let mut optlen = OPTLEN; + getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; + unsafe { + let value = value.assume_init(); + let slice: &[u8] = core::mem::transmute(&value[..optlen as usize]); + assert!(slice.iter().any(|b| *b == b'\0')); + Ok( + core::str::from_utf8(CStr::from_ptr(slice.as_ptr().cast()).to_bytes()) + .unwrap() + .to_owned(), + ) + } +} + +#[inline] +pub(crate) fn set_tcp_thin_linear_timeouts(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_TCP, + c::TCP_THIN_LINEAR_TIMEOUTS, + from_bool(value), + ) +} + +#[inline] +pub(crate) fn get_tcp_thin_linear_timeouts(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_THIN_LINEAR_TIMEOUTS).map(to_bool) +} + +#[inline] +pub(crate) fn set_tcp_cork(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP, c::TCP_CORK, from_bool(value)) +} + +#[inline] +pub(crate) fn get_tcp_cork(fd: BorrowedFd<'_>) -> io::Result<bool> { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_CORK).map(to_bool) +} + +#[inline] +pub(crate) fn get_socket_peercred(fd: BorrowedFd<'_>) -> io::Result<UCred> { + getsockopt(fd, c::SOL_SOCKET, linux_raw_sys::net::SO_PEERCRED) +} + +#[inline] +fn to_ip_mreq(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { + c::ip_mreq { + imr_multiaddr: to_imr_addr(multiaddr), + imr_interface: to_imr_addr(interface), + } +} + +#[inline] +fn to_ip_mreqn(multiaddr: &Ipv4Addr, address: &Ipv4Addr, ifindex: i32) -> c::ip_mreqn { + c::ip_mreqn { + imr_multiaddr: to_imr_addr(multiaddr), + imr_address: to_imr_addr(address), + imr_ifindex: ifindex, + } +} + +#[inline] +fn to_imr_source( + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> c::ip_mreq_source { + c::ip_mreq_source { + imr_multiaddr: to_imr_addr(multiaddr).s_addr, + imr_interface: to_imr_addr(interface).s_addr, + imr_sourceaddr: to_imr_addr(sourceaddr).s_addr, + } +} + +#[inline] +fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { + c::in_addr { + s_addr: u32::from_ne_bytes(addr.octets()), + } +} + +#[inline] +fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { + c::ipv6_mreq { + ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), + ipv6mr_ifindex: to_ipv6mr_interface(interface), + } +} + +#[inline] +fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { + c::in6_addr { + in6_u: linux_raw_sys::net::in6_addr__bindgen_ty_1 { + u6_addr8: multiaddr.octets(), + }, + } +} + +#[inline] +fn to_ipv6mr_interface(interface: u32) -> c::c_int { + interface as c::c_int +} + +#[inline] +fn from_bool(value: bool) -> c::c_uint { + c::c_uint::from(value) +} + +#[inline] +fn to_bool(value: c::c_uint) -> bool { + value != 0 +} + +/// Convert to seconds, rounding up if necessary. +#[inline] +fn duration_to_secs<T: TryFrom<u64>>(duration: Duration) -> io::Result<T> { + let mut secs = duration.as_secs(); + if duration.subsec_nanos() != 0 { + secs = secs.checked_add(1).ok_or(io::Errno::INVAL)?; + } + T::try_from(secs).map_err(|_e| io::Errno::INVAL) +} diff --git a/vendor/rustix/src/backend/linux_raw/net/syscalls.rs b/vendor/rustix/src/backend/linux_raw/net/syscalls.rs index e5ebcc1dd..f513f1261 100644 --- a/vendor/rustix/src/backend/linux_raw/net/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/net/syscalls.rs @@ -30,8 +30,8 @@ use { crate::backend::reg::{ArgReg, SocketArg}, linux_raw_sys::net::{ SYS_ACCEPT, SYS_ACCEPT4, SYS_BIND, SYS_CONNECT, SYS_GETPEERNAME, SYS_GETSOCKNAME, - SYS_GETSOCKOPT, SYS_LISTEN, SYS_RECV, SYS_RECVFROM, SYS_RECVMSG, SYS_SEND, SYS_SENDMSG, - SYS_SENDTO, SYS_SETSOCKOPT, SYS_SHUTDOWN, SYS_SOCKET, SYS_SOCKETPAIR, + SYS_LISTEN, SYS_RECV, SYS_RECVFROM, SYS_RECVMSG, SYS_SEND, SYS_SENDMSG, SYS_SENDTO, + SYS_SHUTDOWN, SYS_SOCKET, SYS_SOCKETPAIR, }, }; @@ -905,627 +905,45 @@ pub(crate) fn connect_unix(fd: BorrowedFd<'_>, addr: &SocketAddrUnix) -> io::Res } #[inline] -pub(crate) fn listen(fd: BorrowedFd<'_>, backlog: c::c_int) -> io::Result<()> { +pub(crate) fn connect_unspec(fd: BorrowedFd<'_>) -> io::Result<()> { + debug_assert_eq!(c::AF_UNSPEC, 0); + let addr = MaybeUninit::<c::sockaddr_storage>::zeroed(); + #[cfg(not(target_arch = "x86"))] unsafe { - ret(syscall_readonly!(__NR_listen, fd, c_int(backlog))) + ret(syscall_readonly!( + __NR_connect, + fd, + by_ref(&addr), + size_of::<c::sockaddr_storage, _>() + )) } #[cfg(target_arch = "x86")] unsafe { ret(syscall_readonly!( __NR_socketcall, - x86_sys(SYS_LISTEN), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[fd.into(), c_int(backlog)]) + x86_sys(SYS_CONNECT), + slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ + fd.into(), + by_ref(&addr), + size_of::<c::sockaddr_storage, _>(), + ]) )) } } -pub(crate) mod sockopt { - use super::{c, BorrowedFd}; - use crate::io; - use crate::net::sockopt::Timeout; - use crate::net::{AddressFamily, Ipv4Addr, Ipv6Addr, SocketType}; - use c::{SO_RCVTIMEO_NEW, SO_RCVTIMEO_OLD, SO_SNDTIMEO_NEW, SO_SNDTIMEO_OLD}; - use core::time::Duration; - use linux_raw_sys::general::{__kernel_timespec, timeval}; - use linux_raw_sys::net::{SO_ACCEPTCONN, TCP_KEEPCNT, TCP_KEEPIDLE, TCP_KEEPINTVL}; - - #[inline] - fn getsockopt<T: Copy>(fd: BorrowedFd<'_>, level: u32, optname: u32) -> io::Result<T> { - use super::*; - - let mut optlen = core::mem::size_of::<T>(); - debug_assert!( - optlen as usize >= core::mem::size_of::<c::c_int>(), - "Socket APIs don't ever use `bool` directly" - ); - - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut value = MaybeUninit::<T>::uninit(); - ret(syscall!( - __NR_getsockopt, - fd, - c_uint(level), - c_uint(optname), - &mut value, - by_mut(&mut optlen) - ))?; - - assert_eq!( - optlen as usize, - core::mem::size_of::<T>(), - "unexpected getsockopt size" - ); - Ok(value.assume_init()) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut value = MaybeUninit::<T>::uninit(); - ret(syscall!( - __NR_socketcall, - x86_sys(SYS_GETSOCKOPT), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - c_uint(level), - c_uint(optname), - (&mut value).into(), - by_mut(&mut optlen), - ]) - ))?; - assert_eq!( - optlen as usize, - core::mem::size_of::<T>(), - "unexpected getsockopt size" - ); - Ok(value.assume_init()) - } - } - - #[inline] - fn setsockopt<T: Copy>( - fd: BorrowedFd<'_>, - level: u32, - optname: u32, - value: T, - ) -> io::Result<()> { - use super::*; - - let optlen = core::mem::size_of::<T>().try_into().unwrap(); - debug_assert!( - optlen as usize >= core::mem::size_of::<c::c_int>(), - "Socket APIs don't ever use `bool` directly" - ); - - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_setsockopt, - fd, - c_uint(level), - c_uint(optname), - by_ref(&value), - socklen_t(optlen) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SETSOCKOPT), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - c_uint(level), - c_uint(optname), - by_ref(&value), - socklen_t(optlen), - ]) - )) - } - } - - #[inline] - pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result<SocketType> { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_TYPE) - } - - #[inline] - pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_REUSEADDR, - from_bool(reuseaddr), - ) - } - - #[inline] - pub(crate) fn get_socket_reuseaddr(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_REUSEADDR).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_BROADCAST, - from_bool(broadcast), - ) - } - - #[inline] - pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_BROADCAST).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_linger( - fd: BorrowedFd<'_>, - linger: Option<Duration>, - ) -> io::Result<()> { - // Convert `linger` to seconds, rounding up. - let l_linger = if let Some(linger) = linger { - duration_to_secs(linger)? - } else { - 0 - }; - let linger = c::linger { - l_onoff: c::c_int::from(linger.is_some()), - l_linger, - }; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER, linger) - } - - #[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)?; - Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) - } - - #[inline] - pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED, from_bool(passcred)) - } - - #[inline] - pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option<Duration>, - ) -> io::Result<()> { - let time = duration_to_linux(timeout)?; - let optname = match id { - Timeout::Recv => SO_RCVTIMEO_NEW, - Timeout::Send => SO_SNDTIMEO_NEW, - }; - match setsockopt(fd, c::SOL_SOCKET, optname, time) { - Err(io::Errno::NOPROTOOPT) if SO_RCVTIMEO_NEW != SO_RCVTIMEO_OLD => { - set_socket_timeout_old(fd, id, timeout) - } - otherwise => otherwise, - } - } - - /// Same as `set_socket_timeout` but uses `timeval` instead of - /// `__kernel_timespec` and `_OLD` constants instead of `_NEW`. - fn set_socket_timeout_old( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option<Duration>, - ) -> io::Result<()> { - let time = duration_to_linux_old(timeout)?; - let optname = match id { - Timeout::Recv => SO_RCVTIMEO_OLD, - Timeout::Send => SO_SNDTIMEO_OLD, - }; - setsockopt(fd, c::SOL_SOCKET, optname, time) - } - - #[inline] - pub(crate) fn get_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - ) -> io::Result<Option<Duration>> { - let optname = match id { - Timeout::Recv => SO_RCVTIMEO_NEW, - Timeout::Send => SO_SNDTIMEO_NEW, - }; - let time: __kernel_timespec = match getsockopt(fd, c::SOL_SOCKET, optname) { - Err(io::Errno::NOPROTOOPT) if SO_RCVTIMEO_NEW != SO_RCVTIMEO_OLD => { - return get_socket_timeout_old(fd, id) - } - otherwise => otherwise?, - }; - Ok(duration_from_linux(time)) - } - - /// Same as `get_socket_timeout` but uses `timeval` instead of - /// `__kernel_timespec` and `_OLD` constants instead of `_NEW`. - fn get_socket_timeout_old(fd: BorrowedFd<'_>, id: Timeout) -> io::Result<Option<Duration>> { - let optname = match id { - Timeout::Recv => SO_RCVTIMEO_OLD, - Timeout::Send => SO_SNDTIMEO_OLD, - }; - let time: timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; - Ok(duration_from_linux_old(time)) - } - - /// Convert a C `timespec` to a Rust `Option<Duration>`. - #[inline] - fn duration_from_linux(time: __kernel_timespec) -> Option<Duration> { - if time.tv_sec == 0 && time.tv_nsec == 0 { - None - } else { - Some( - Duration::from_secs(time.tv_sec as u64) + Duration::from_nanos(time.tv_nsec as u64), - ) - } - } - - /// Like `duration_from_linux` but uses Linux's old 32-bit `timeval`. - fn duration_from_linux_old(time: timeval) -> Option<Duration> { - if time.tv_sec == 0 && time.tv_usec == 0 { - None - } else { - Some( - Duration::from_secs(time.tv_sec as u64) - + Duration::from_micros(time.tv_usec as u64), - ) - } - } - - /// Convert a Rust `Option<Duration>` to a C `timespec`. - #[inline] - fn duration_to_linux(timeout: Option<Duration>) -> io::Result<__kernel_timespec> { - Ok(match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - let mut timeout = __kernel_timespec { - tv_sec: timeout.as_secs().try_into().unwrap_or(i64::MAX), - tv_nsec: timeout.subsec_nanos().into(), - }; - if timeout.tv_sec == 0 && timeout.tv_nsec == 0 { - timeout.tv_nsec = 1; - } - timeout - } - None => __kernel_timespec { - tv_sec: 0, - tv_nsec: 0, - }, - }) - } - - /// Like `duration_to_linux` but uses Linux's old 32-bit `timeval`. - fn duration_to_linux_old(timeout: Option<Duration>) -> io::Result<timeval> { - Ok(match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - - // `subsec_micros` rounds down, so we use `subsec_nanos` and - // manually round up. - let mut timeout = timeval { - tv_sec: timeout.as_secs().try_into().unwrap_or(c::c_long::MAX), - tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => timeval { - tv_sec: 0, - tv_usec: 0, - }, - }) - } - - #[inline] - pub(crate) fn get_socket_error(fd: BorrowedFd<'_>) -> io::Result<Result<(), io::Errno>> { - let err: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_ERROR)?; - Ok(if err == 0 { - Ok(()) - } else { - Err(io::Errno::from_raw_os_error(err)) - }) - } - - #[inline] - pub(crate) fn set_socket_keepalive(fd: BorrowedFd<'_>, keepalive: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_KEEPALIVE, - from_bool(keepalive), - ) - } - - #[inline] - pub(crate) fn get_socket_keepalive(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_KEEPALIVE).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::OVERFLOW)?; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF, size) - } - - #[inline] - pub(crate) fn get_socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result<usize> { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF).map(|size: u32| size as usize) - } - - #[inline] - pub(crate) fn set_socket_send_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::OVERFLOW)?; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF, size) - } - - #[inline] - pub(crate) fn get_socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result<usize> { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF).map(|size: u32| size as usize) +#[inline] +pub(crate) fn listen(fd: BorrowedFd<'_>, backlog: c::c_int) -> io::Result<()> { + #[cfg(not(target_arch = "x86"))] + unsafe { + ret(syscall_readonly!(__NR_listen, fd, c_int(backlog))) } - - #[inline] - pub(crate) fn get_socket_domain(fd: BorrowedFd<'_>) -> io::Result<AddressFamily> { - let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_DOMAIN)?; - Ok(AddressFamily( - domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?, + #[cfg(target_arch = "x86")] + unsafe { + ret(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_LISTEN), + slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[fd.into(), c_int(backlog)]) )) } - - #[inline] - pub(crate) fn get_socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET as _, SO_ACCEPTCONN).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL, ttl) - } - - #[inline] - pub(crate) fn get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL) - } - - #[inline] - pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY, from_bool(only_v6)) - } - - #[inline] - pub(crate) fn get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_multicast_loop( - fd: BorrowedFd<'_>, - multicast_loop: bool, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP as _, - c::IP_MULTICAST_LOOP, - from_bool(multicast_loop), - ) - } - - #[inline] - pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_LOOP).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL, multicast_ttl) - } - - #[inline] - pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL) - } - - #[inline] - pub(crate) fn set_ipv6_multicast_loop( - fd: BorrowedFd<'_>, - multicast_loop: bool, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IPV6 as _, - c::IPV6_MULTICAST_LOOP, - from_bool(multicast_loop), - ) - } - - #[inline] - pub(crate) fn get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_MULTICAST_LOOP).map(to_bool) - } - - #[inline] - pub(crate) fn set_ipv6_multicast_hops( - fd: BorrowedFd<'_>, - multicast_hops: u32, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP as _, - 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_HOPS) - } - - #[inline] - pub(crate) fn set_ip_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_ADD_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ipv6_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, - ) -> io::Result<()> { - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_ADD_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ip_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_DROP_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ipv6_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, - ) -> io::Result<()> { - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_DROP_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn get_ipv6_unicast_hops(fd: BorrowedFd<'_>) -> io::Result<u8> { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) - } - - #[inline] - pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option<u8>) -> io::Result<()> { - let hops = match hops { - Some(hops) => hops.into(), - None => -1, - }; - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS, hops) - } - - #[inline] - pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY, from_bool(nodelay)) - } - - #[inline] - pub(crate) fn get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY).map(to_bool) - } - - #[inline] - pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPCNT, count) - } - - #[inline] - pub(crate) fn get_tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPCNT) - } - - #[inline] - pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPIDLE, secs) - } - - #[inline] - pub(crate) fn get_tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result<Duration> { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPIDLE)?; - Ok(Duration::from_secs(secs as u64)) - } - - #[inline] - pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPINTVL, secs) - } - - #[inline] - pub(crate) fn get_tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result<Duration> { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPINTVL)?; - Ok(Duration::from_secs(secs as u64)) - } - - #[inline] - fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { - c::ip_mreq { - imr_multiaddr: to_imr_addr(multiaddr), - imr_interface: to_imr_addr(interface), - } - } - - #[inline] - fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { - c::in_addr { - s_addr: u32::from_ne_bytes(addr.octets()), - } - } - - #[inline] - fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { - c::ipv6_mreq { - ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), - ipv6mr_ifindex: to_ipv6mr_interface(interface), - } - } - - #[inline] - fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { - c::in6_addr { - in6_u: linux_raw_sys::net::in6_addr__bindgen_ty_1 { - u6_addr8: multiaddr.octets(), - }, - } - } - - #[inline] - fn to_ipv6mr_interface(interface: u32) -> c::c_int { - interface as c::c_int - } - - #[inline] - fn from_bool(value: bool) -> c::c_uint { - c::c_uint::from(value) - } - - #[inline] - fn to_bool(value: c::c_uint) -> bool { - value != 0 - } - - /// Convert to seconds, rounding up if necessary. - #[inline] - fn duration_to_secs<T: TryFrom<u64>>(duration: Duration) -> io::Result<T> { - let mut secs = duration.as_secs(); - if duration.subsec_nanos() != 0 { - secs = secs.checked_add(1).ok_or(io::Errno::INVAL)?; - } - T::try_from(secs).map_err(|_e| io::Errno::INVAL) - } } diff --git a/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs b/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs index 417f76e43..24edd4948 100644 --- a/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs +++ b/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs @@ -1,5 +1,5 @@ -//! 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. +//! 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. #![allow(unsafe_code)] use crate::backend::c; diff --git a/vendor/rustix/src/backend/linux_raw/param/auxv.rs b/vendor/rustix/src/backend/linux_raw/param/auxv.rs index 8b0423ae4..fbbcdea29 100644 --- a/vendor/rustix/src/backend/linux_raw/param/auxv.rs +++ b/vendor/rustix/src/backend/linux_raw/param/auxv.rs @@ -15,6 +15,8 @@ use crate::utils::{as_ptr, check_raw_pointer}; use alloc::vec::Vec; use core::mem::size_of; use core::ptr::{null_mut, read_unaligned, NonNull}; +#[cfg(feature = "runtime")] +use core::sync::atomic::AtomicU8; use core::sync::atomic::Ordering::Relaxed; use core::sync::atomic::{AtomicPtr, AtomicUsize}; use linux_raw_sys::elf::*; @@ -22,7 +24,9 @@ use linux_raw_sys::general::{ AT_BASE, AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_NULL, AT_PAGESZ, AT_SYSINFO_EHDR, }; #[cfg(feature = "runtime")] -use linux_raw_sys::general::{AT_ENTRY, AT_PHDR, AT_PHENT, AT_PHNUM}; +use linux_raw_sys::general::{ + AT_EGID, AT_ENTRY, AT_EUID, AT_GID, AT_PHDR, AT_PHENT, AT_PHNUM, AT_SECURE, AT_UID, +}; #[cfg(feature = "param")] #[inline] @@ -82,6 +86,23 @@ pub(crate) fn linux_execfn() -> &'static CStr { #[cfg(feature = "runtime")] #[inline] +pub(crate) fn linux_secure() -> bool { + let mut secure = SECURE.load(Relaxed); + + // 0 means not initialized yet. + if secure == 0 { + init_auxv(); + secure = SECURE.load(Relaxed); + } + + // 0 means not present. Libc `getauxval(AT_SECURE)` would return 0. + // 1 means not in secure mode. + // 2 means in secure mode. + secure > 1 +} + +#[cfg(feature = "runtime")] +#[inline] pub(crate) fn exe_phdrs() -> (*const c::c_void, usize, usize) { let mut phdr = PHDR.load(Relaxed); let mut phent = PHENT.load(Relaxed); @@ -131,6 +152,8 @@ static HWCAP2: AtomicUsize = AtomicUsize::new(0); static EXECFN: AtomicPtr<c::c_char> = AtomicPtr::new(null_mut()); static SYSINFO_EHDR: AtomicPtr<Elf_Ehdr> = AtomicPtr::new(null_mut()); #[cfg(feature = "runtime")] +static SECURE: AtomicU8 = AtomicU8::new(0); +#[cfg(feature = "runtime")] static PHDR: AtomicPtr<Elf_Phdr> = AtomicPtr::new(null_mut()); #[cfg(feature = "runtime")] static PHENT: AtomicUsize = AtomicUsize::new(0); @@ -142,7 +165,7 @@ static ENTRY: AtomicUsize = AtomicUsize::new(0); #[cfg(feature = "alloc")] fn pr_get_auxv() -> crate::io::Result<Vec<u8>> { use super::super::conv::{c_int, pass_usize, ret_usize}; - const PR_GET_AUXV: c::c_int = 0x41555856; + const PR_GET_AUXV: c::c_int = 0x4155_5856; let mut buffer = alloc::vec![0u8; 512]; let len = unsafe { ret_usize(syscall_always_asm!( @@ -256,6 +279,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti let mut execfn = null_mut(); let mut sysinfo_ehdr = null_mut(); #[cfg(feature = "runtime")] + let mut secure = 0; + #[cfg(feature = "runtime")] let mut phdr = null_mut(); #[cfg(feature = "runtime")] let mut phnum = 0; @@ -263,6 +288,14 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti let mut phent = 0; #[cfg(feature = "runtime")] let mut entry = 0; + #[cfg(feature = "runtime")] + let mut uid = None; + #[cfg(feature = "runtime")] + let mut euid = None; + #[cfg(feature = "runtime")] + let mut gid = None; + #[cfg(feature = "runtime")] + let mut egid = None; for Elf_auxv_t { a_type, a_val } in aux_iter { match a_type as _ { @@ -278,6 +311,16 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti } #[cfg(feature = "runtime")] + AT_SECURE => secure = (a_val as usize != 0) as u8 + 1, + #[cfg(feature = "runtime")] + AT_UID => uid = Some(a_val), + #[cfg(feature = "runtime")] + AT_EUID => euid = Some(a_val), + #[cfg(feature = "runtime")] + AT_GID => gid = Some(a_val), + #[cfg(feature = "runtime")] + AT_EGID => egid = Some(a_val), + #[cfg(feature = "runtime")] AT_PHDR => phdr = check_raw_pointer::<Elf_Phdr>(a_val as *mut _)?.as_ptr(), #[cfg(feature = "runtime")] AT_PHNUM => phnum = a_val as usize, @@ -294,8 +337,16 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti #[cfg(feature = "runtime")] assert_eq!(phent, size_of::<Elf_Phdr>()); - // The base and sysinfo_ehdr (if present) matches our platform. Accept - // the aux values. + // If we're running set-uid or set-gid, enable “secure execution” mode, + // which doesn't do much, but users may be depending on the things that + // it does do. + #[cfg(feature = "runtime")] + if uid != euid || gid != egid { + secure = 2; + } + + // The base and sysinfo_ehdr (if present) matches our platform. Accept the + // aux values. PAGE_SIZE.store(pagesz, Relaxed); CLOCK_TICKS_PER_SECOND.store(clktck, Relaxed); HWCAP.store(hwcap, Relaxed); @@ -303,6 +354,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti EXECFN.store(execfn, Relaxed); SYSINFO_EHDR.store(sysinfo_ehdr, Relaxed); #[cfg(feature = "runtime")] + SECURE.store(secure, Relaxed); + #[cfg(feature = "runtime")] PHDR.store(phdr, Relaxed); #[cfg(feature = "runtime")] PHNUM.store(phnum, Relaxed); diff --git a/vendor/rustix/src/backend/linux_raw/param/init.rs b/vendor/rustix/src/backend/linux_raw/param/init.rs index 46aae009a..a63212507 100644 --- a/vendor/rustix/src/backend/linux_raw/param/init.rs +++ b/vendor/rustix/src/backend/linux_raw/param/init.rs @@ -10,13 +10,15 @@ use crate::backend::c; use crate::ffi::CStr; use core::ffi::c_void; use core::ptr::{null_mut, read, NonNull}; +#[cfg(feature = "runtime")] +use core::sync::atomic::AtomicBool; use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; use linux_raw_sys::elf::*; use linux_raw_sys::general::{ AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_NULL, AT_PAGESZ, AT_SYSINFO_EHDR, }; #[cfg(feature = "runtime")] -use linux_raw_sys::general::{AT_ENTRY, AT_PHDR, AT_PHENT, AT_PHNUM}; +use linux_raw_sys::general::{AT_ENTRY, AT_PHDR, AT_PHENT, AT_PHNUM, AT_SECURE}; #[cfg(feature = "param")] #[inline] @@ -53,6 +55,12 @@ pub(crate) fn linux_execfn() -> &'static CStr { #[cfg(feature = "runtime")] #[inline] +pub(crate) fn linux_secure() -> bool { + unsafe { SECURE.load(Ordering::Relaxed) } +} + +#[cfg(feature = "runtime")] +#[inline] pub(crate) fn exe_phdrs() -> (*const c_void, usize, usize) { unsafe { ( @@ -84,6 +92,8 @@ static mut SYSINFO_EHDR: AtomicPtr<Elf_Ehdr> = AtomicPtr::new(null_mut()); // Initialize `EXECFN` to a valid `CStr` pointer so that we don't need to check // for null on every `execfn` call. static mut EXECFN: AtomicPtr<c::c_char> = AtomicPtr::new(b"\0".as_ptr() as _); +#[cfg(feature = "runtime")] +static mut SECURE: AtomicBool = AtomicBool::new(false); // Use `dangling` so that we can always treat it like an empty slice. #[cfg(feature = "runtime")] static mut PHDR: AtomicPtr<Elf_Phdr> = AtomicPtr::new(NonNull::dangling().as_ptr()); @@ -133,6 +143,8 @@ unsafe fn init_from_auxp(mut auxp: *const Elf_auxv_t) { AT_SYSINFO_EHDR => SYSINFO_EHDR.store(a_val.cast::<Elf_Ehdr>(), Ordering::Relaxed), #[cfg(feature = "runtime")] + AT_SECURE => SECURE.store(a_val as usize != 0, Ordering::Relaxed), + #[cfg(feature = "runtime")] AT_PHDR => PHDR.store(a_val.cast::<Elf_Phdr>(), Ordering::Relaxed), #[cfg(feature = "runtime")] AT_PHNUM => PHNUM.store(a_val as usize, Ordering::Relaxed), diff --git a/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs b/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs index 0e6ca6ed5..311cf961b 100644 --- a/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs +++ b/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs @@ -34,6 +34,7 @@ const AT_PHNUM: c::c_ulong = 5; const AT_ENTRY: c::c_ulong = 9; const AT_HWCAP: c::c_ulong = 16; const AT_HWCAP2: c::c_ulong = 26; +const AT_SECURE: c::c_ulong = 23; const AT_EXECFN: c::c_ulong = 31; const AT_SYSINFO_EHDR: c::c_ulong = 33; @@ -59,6 +60,7 @@ fn test_abi() { const_assert_eq!(self::AT_HWCAP, ::libc::AT_HWCAP); const_assert_eq!(self::AT_HWCAP2, ::libc::AT_HWCAP2); const_assert_eq!(self::AT_EXECFN, ::libc::AT_EXECFN); + const_assert_eq!(self::AT_SECURE, ::libc::AT_SECURE); const_assert_eq!(self::AT_SYSINFO_EHDR, ::libc::AT_SYSINFO_EHDR); #[cfg(feature = "runtime")] const_assert_eq!(self::AT_PHDR, ::libc::AT_PHDR); @@ -122,6 +124,12 @@ pub(crate) fn linux_execfn() -> &'static CStr { #[cfg(feature = "runtime")] #[inline] +pub(crate) fn linux_secure() -> bool { + unsafe { getauxval(AT_SECURE) as usize != 0 } +} + +#[cfg(feature = "runtime")] +#[inline] pub(crate) fn exe_phdrs() -> (*const c::c_void, usize, usize) { unsafe { let phdr = getauxval(AT_PHDR) as *const c::c_void; @@ -131,8 +139,8 @@ pub(crate) fn exe_phdrs() -> (*const c::c_void, usize, usize) { } } -/// `AT_SYSINFO_EHDR` isn't present on all platforms in all configurations, -/// so if we don't see it, this function returns a null pointer. +/// `AT_SYSINFO_EHDR` isn't present on all platforms in all configurations, so +/// if we don't see it, this function returns a null pointer. #[inline] pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr { #[cfg(not(feature = "runtime"))] diff --git a/vendor/rustix/src/backend/linux_raw/pipe/types.rs b/vendor/rustix/src/backend/linux_raw/pipe/types.rs index c950b5d0a..fdddb89e1 100644 --- a/vendor/rustix/src/backend/linux_raw/pipe/types.rs +++ b/vendor/rustix/src/backend/linux_raw/pipe/types.rs @@ -16,7 +16,7 @@ bitflags! { /// `O_NONBLOCK` const NONBLOCK = linux_raw_sys::general::O_NONBLOCK; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -36,7 +36,7 @@ bitflags! { /// `SPLICE_F_GIFT` const GIFT = linux_raw_sys::general::SPLICE_F_GIFT; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/process/syscalls.rs b/vendor/rustix/src/backend/linux_raw/process/syscalls.rs index c0416bf5a..931f2ff2a 100644 --- a/vendor/rustix/src/backend/linux_raw/process/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/process/syscalls.rs @@ -141,7 +141,7 @@ pub(crate) fn getpgrp() -> Pid { #[inline] pub(crate) fn sched_getaffinity(pid: Option<Pid>, cpuset: &mut RawCpuSet) -> io::Result<()> { unsafe { - // The raw linux syscall returns the size (in bytes) of the `cpumask_t` + // The raw Linux syscall returns the size (in bytes) of the `cpumask_t` // data type that is used internally by the kernel to represent the CPU // set bit mask. let size = ret_usize(syscall!( @@ -436,6 +436,11 @@ pub(crate) fn waitpid( } #[inline] +pub(crate) fn waitpgid(pgid: Pid, waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> { + _waitpid(-pgid.as_raw_nonzero().get(), waitopts) +} + +#[inline] pub(crate) fn _waitpid( pid: RawPid, waitopts: WaitOptions, @@ -459,6 +464,7 @@ pub(crate) fn waitid(id: WaitId<'_>, options: WaitidOptions) -> io::Result<Optio match id { WaitId::All => _waitid_all(options), WaitId::Pid(pid) => _waitid_pid(pid, options), + WaitId::Pgid(pid) => _waitid_pgid(pid, options), WaitId::PidFd(fd) => _waitid_pidfd(fd, options), } } @@ -502,6 +508,25 @@ fn _waitid_pid(pid: Pid, options: WaitidOptions) -> io::Result<Option<WaitidStat } #[inline] +fn _waitid_pgid(pgid: Option<Pid>, options: WaitidOptions) -> io::Result<Option<WaitidStatus>> { + // `waitid` can return successfully without initializing the struct (no + // children found when using `WNOHANG`) + let mut status = MaybeUninit::<c::siginfo_t>::zeroed(); + unsafe { + ret(syscall!( + __NR_waitid, + c_uint(c::P_PGID), + c_int(Pid::as_raw(pgid)), + by_mut(&mut status), + c_int(options.bits() as _), + zero() + ))? + }; + + Ok(unsafe { cvt_waitid_status(status) }) +} + +#[inline] fn _waitid_pidfd(fd: BorrowedFd<'_>, options: WaitidOptions) -> io::Result<Option<WaitidStatus>> { // `waitid` can return successfully without initializing the struct (no // children found when using `WNOHANG`) diff --git a/vendor/rustix/src/backend/linux_raw/rand/types.rs b/vendor/rustix/src/backend/linux_raw/rand/types.rs index 47b996d30..9bc857fdd 100644 --- a/vendor/rustix/src/backend/linux_raw/rand/types.rs +++ b/vendor/rustix/src/backend/linux_raw/rand/types.rs @@ -14,7 +14,7 @@ bitflags! { /// `GRND_INSECURE` const INSECURE = linux_raw_sys::general::GRND_INSECURE; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/reg.rs b/vendor/rustix/src/backend/linux_raw/reg.rs index c4e495c52..10f95a5f9 100644 --- a/vendor/rustix/src/backend/linux_raw/reg.rs +++ b/vendor/rustix/src/backend/linux_raw/reg.rs @@ -1,8 +1,8 @@ //! Encapsulation for system call arguments and return values. //! //! The inline-asm code paths do some amount of reordering of arguments; to -//! ensure that we don't accidentally misroute an argument or return value, -//! we use distinct types for each argument index and return value. +//! ensure that we don't accidentally misroute an argument or return value, we +//! use distinct types for each argument index and return value. //! //! # Safety //! @@ -23,8 +23,8 @@ pub(super) trait ToAsm: private::Sealed { /// /// # Safety /// - /// This should be used immediately before the syscall instruction, and - /// the returned value shouldn't be used for any other purpose. + /// This should be used immediately before the syscall instruction, and the + /// returned value shouldn't be used for any other purpose. #[must_use] unsafe fn to_asm(self) -> *mut Opaque; } @@ -35,8 +35,8 @@ pub(super) trait FromAsm: private::Sealed { /// /// # Safety /// - /// This should be used immediately after the syscall instruction, and - /// the operand value shouldn't be used for any other purpose. + /// This should be used immediately after the syscall instruction, and the + /// operand value shouldn't be used for any other purpose. #[must_use] unsafe fn from_asm(raw: *mut Opaque) -> Self; } diff --git a/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs b/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs index c1ff3d239..1bc461c04 100644 --- a/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs @@ -9,7 +9,8 @@ use crate::backend::c; #[cfg(target_arch = "x86")] use crate::backend::conv::by_mut; use crate::backend::conv::{ - by_ref, c_int, c_uint, ret, ret_c_int, ret_c_int_infallible, ret_error, size_of, zero, + by_ref, c_int, c_uint, ret, ret_c_int, ret_c_int_infallible, ret_error, ret_void_star, size_of, + zero, }; #[cfg(feature = "fs")] use crate::fd::BorrowedFd; @@ -22,6 +23,7 @@ use crate::runtime::{How, Sigaction, Siginfo, Sigset, Stack}; use crate::signal::Signal; use crate::timespec::Timespec; use crate::utils::option_as_ptr; +use core::ffi::c_void; use core::mem::MaybeUninit; #[cfg(target_pointer_width = "32")] use linux_raw_sys::general::__kernel_old_timespec; @@ -263,3 +265,9 @@ unsafe fn sigtimedwait_old( pub(crate) fn exit_group(code: c::c_int) -> ! { unsafe { syscall_noreturn!(__NR_exit_group, c_int(code)) } } + +#[inline] +pub(crate) unsafe fn brk(addr: *mut c::c_void) -> io::Result<*mut c_void> { + // Don't mark this `readonly`, so that loads don't get reordered past it. + ret_void_star(syscall!(__NR_brk, addr)) +} diff --git a/vendor/rustix/src/backend/linux_raw/runtime/tls.rs b/vendor/rustix/src/backend/linux_raw/runtime/tls.rs index ad1634894..69bd5cef1 100644 --- a/vendor/rustix/src/backend/linux_raw/runtime/tls.rs +++ b/vendor/rustix/src/backend/linux_raw/runtime/tls.rs @@ -8,6 +8,7 @@ use crate::backend::c; use crate::backend::param::auxv::exe_phdrs; +use core::arch::global_asm; use core::ptr::{null, NonNull}; use linux_raw_sys::elf::*; @@ -25,6 +26,10 @@ pub(crate) fn startup_tls_info() -> StartupTlsInfo { let (first_phdr, phent, phnum) = exe_phdrs(); let mut current_phdr = first_phdr.cast::<Elf_Phdr>(); + // The dynamic address of the dynamic section, which we can compare with + // the `PT_DYNAMIC` header's static address, if present. + let dynamic_addr: *const c::c_void = unsafe { &_DYNAMIC }; + // SAFETY: We assume the phdr array pointer and length the kernel provided // to the process describe a valid phdr array. unsafe { @@ -34,7 +39,13 @@ pub(crate) fn startup_tls_info() -> StartupTlsInfo { current_phdr = current_phdr.cast::<u8>().add(phent).cast(); match phdr.p_type { - PT_PHDR => base = first_phdr.cast::<u8>().sub(phdr.p_vaddr), + // Compute the offset from the static virtual addresses + // in the `p_vaddr` fields to the dynamic addresses. We don't + // always get a `PT_PHDR` or `PT_DYNAMIC` header, so use + // whichever one we get. + PT_PHDR => base = first_phdr.cast::<u8>().wrapping_sub(phdr.p_vaddr), + PT_DYNAMIC => base = dynamic_addr.cast::<u8>().wrapping_sub(phdr.p_vaddr), + PT_TLS => tls_phdr = phdr, PT_GNU_STACK => stack_size = phdr.p_memsz, _ => {} @@ -51,7 +62,7 @@ pub(crate) fn startup_tls_info() -> StartupTlsInfo { } } else { StartupTlsInfo { - addr: base.cast::<u8>().add((*tls_phdr).p_vaddr).cast(), + addr: base.cast::<u8>().wrapping_add((*tls_phdr).p_vaddr).cast(), mem_size: (*tls_phdr).p_memsz, file_size: (*tls_phdr).p_filesz, align: (*tls_phdr).p_align, @@ -61,6 +72,15 @@ pub(crate) fn startup_tls_info() -> StartupTlsInfo { } } +extern "C" { + /// Declare the `_DYNAMIC` symbol so that we can compare its address with + /// the static address in the `PT_DYNAMIC` header to learn our offset. Use + /// a weak symbol because `_DYNAMIC` is not always present. + static _DYNAMIC: c::c_void; +} +// Rust has `extern_weak` but it isn't stable, so use a `global_asm`. +global_asm!(".weak _DYNAMIC"); + /// The values returned from [`startup_tls_info`]. /// /// [`startup_tls_info`]: crate::runtime::startup_tls_info diff --git a/vendor/rustix/src/backend/linux_raw/shm/mod.rs b/vendor/rustix/src/backend/linux_raw/shm/mod.rs new file mode 100644 index 000000000..1e0181a99 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/shm/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/shm/syscalls.rs b/vendor/rustix/src/backend/linux_raw/shm/syscalls.rs new file mode 100644 index 000000000..3b083f4b5 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/shm/syscalls.rs @@ -0,0 +1,47 @@ +use crate::ffi::CStr; + +use crate::backend::fs::syscalls::{open, unlink}; +use crate::backend::fs::types::{Mode, OFlags}; +use crate::fd::OwnedFd; +use crate::io; +use crate::shm::ShmOFlags; + +const NAME_MAX: usize = 255; +const SHM_DIR: &[u8] = b"/dev/shm/"; + +fn get_shm_name(name: &CStr) -> io::Result<([u8; NAME_MAX + SHM_DIR.len() + 1], usize)> { + let name = name.to_bytes(); + + if name.len() > NAME_MAX { + return Err(io::Errno::NAMETOOLONG); + } + + let num_slashes = name.iter().take_while(|x| **x == b'/').count(); + let after_slashes = &name[num_slashes..]; + if after_slashes.is_empty() + || after_slashes == b"." + || after_slashes == b".." + || after_slashes.contains(&b'/') + { + return Err(io::Errno::INVAL); + } + + let mut path = [0; NAME_MAX + SHM_DIR.len() + 1]; + path[..SHM_DIR.len()].copy_from_slice(SHM_DIR); + path[SHM_DIR.len()..SHM_DIR.len() + name.len()].copy_from_slice(name); + Ok((path, SHM_DIR.len() + name.len() + 1)) +} + +pub(crate) fn shm_open(name: &CStr, oflags: ShmOFlags, mode: Mode) -> io::Result<OwnedFd> { + let (path, len) = get_shm_name(name)?; + open( + CStr::from_bytes_with_nul(&path[..len]).unwrap(), + OFlags::from_bits(oflags.bits()).unwrap() | OFlags::CLOEXEC, + mode, + ) +} + +pub(crate) fn shm_unlink(name: &CStr) -> io::Result<()> { + let (path, len) = get_shm_name(name)?; + unlink(CStr::from_bytes_with_nul(&path[..len]).unwrap()) +} diff --git a/vendor/rustix/src/backend/linux_raw/shm/types.rs b/vendor/rustix/src/backend/linux_raw/shm/types.rs new file mode 100644 index 000000000..3343d4424 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/shm/types.rs @@ -0,0 +1,30 @@ +use crate::backend::c; +use bitflags::bitflags; + +bitflags! { + /// `O_*` constants for use with [`shm_open`]. + /// + /// [`shm_open`]: crate:shm::shm_open + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct ShmOFlags: c::c_uint { + /// `O_CREAT` + #[doc(alias = "CREAT")] + const CREATE = linux_raw_sys::general::O_CREAT; + + /// `O_EXCL` + const EXCL = linux_raw_sys::general::O_EXCL; + + /// `O_RDONLY` + const RDONLY = linux_raw_sys::general::O_RDONLY; + + /// `O_RDWR` + const RDWR = linux_raw_sys::general::O_RDWR; + + /// `O_TRUNC` + const TRUNC = linux_raw_sys::general::O_TRUNC; + + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> + const _ = !0; + } +} diff --git a/vendor/rustix/src/backend/linux_raw/system/syscalls.rs b/vendor/rustix/src/backend/linux_raw/system/syscalls.rs index 947d5168e..6b41cdbab 100644 --- a/vendor/rustix/src/backend/linux_raw/system/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/system/syscalls.rs @@ -6,9 +6,10 @@ #![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] use super::types::RawUname; -use crate::backend::conv::{ret, ret_infallible, slice}; +use crate::backend::c; +use crate::backend::conv::{c_int, ret, ret_infallible, slice}; use crate::io; -use crate::system::Sysinfo; +use crate::system::{RebootCommand, Sysinfo}; use core::mem::MaybeUninit; #[inline] @@ -34,3 +35,15 @@ pub(crate) fn sethostname(name: &[u8]) -> io::Result<()> { let (ptr, len) = slice(name); unsafe { ret(syscall_readonly!(__NR_sethostname, ptr, len)) } } + +#[inline] +pub(crate) fn reboot(cmd: RebootCommand) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_reboot, + c_int(c::LINUX_REBOOT_MAGIC1), + c_int(c::LINUX_REBOOT_MAGIC2), + c_int(cmd as i32) + )) + } +} diff --git a/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs b/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs index 09100441f..d2fe91236 100644 --- a/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs @@ -37,8 +37,46 @@ pub(crate) fn tcgetwinsize(fd: BorrowedFd<'_>) -> io::Result<Winsize> { pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result<Termios> { unsafe { let mut result = MaybeUninit::<Termios>::uninit(); + + // QEMU's `TCGETS2` doesn't currently set `input_speed` or + // `output_speed` on PowerPC, so zero out the fields ourselves. + #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] + { + result.write(core::mem::zeroed()); + } + ret(syscall!(__NR_ioctl, fd, c_uint(c::TCGETS2), &mut result))?; - Ok(result.assume_init()) + + let result = result.assume_init(); + + // QEMU's `TCGETS2` doesn't currently set `input_speed` or + // `output_speed` on PowerPC, so set them manually if we can. + #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] + let result = { + use crate::termios::speed; + let mut result = result; + if result.output_speed == 0 && (result.control_modes.bits() & c::CBAUD) != c::BOTHER { + if let Some(output_speed) = speed::decode(result.control_modes.bits() & c::CBAUD) { + result.output_speed = output_speed; + } + } + if result.input_speed == 0 + && ((result.control_modes.bits() & c::CIBAUD) >> c::IBSHIFT) != c::BOTHER + { + // For input speeds, `B0` is special-cased to mean the input + // speed is the same as the output speed. + if ((result.control_modes.bits() & c::CIBAUD) >> c::IBSHIFT) == c::B0 { + result.input_speed = result.output_speed; + } else if let Some(input_speed) = + speed::decode((result.control_modes.bits() & c::CIBAUD) >> c::IBSHIFT) + { + result.input_speed = input_speed; + } + } + result + }; + + Ok(result) } } @@ -240,7 +278,7 @@ pub(crate) fn ttyname(fd: BorrowedFd<'_>, buf: &mut [MaybeUninit<u8>]) -> io::Re // Check that `fd` is really a tty. tcgetwinsize(fd)?; - // Get a fd to '/proc/self/fd'. + // Get a fd to "/proc/self/fd". let proc_self_fd = procfs::proc_self_fd()?; // Gather the ttyname by reading the "fd" file inside `proc_self_fd`. diff --git a/vendor/rustix/src/backend/linux_raw/time/types.rs b/vendor/rustix/src/backend/linux_raw/time/types.rs index ab43aed7c..f3e653b0a 100644 --- a/vendor/rustix/src/backend/linux_raw/time/types.rs +++ b/vendor/rustix/src/backend/linux_raw/time/types.rs @@ -21,7 +21,7 @@ bitflags! { /// `TFD_CLOEXEC` const CLOEXEC = linux_raw_sys::general::TFD_CLOEXEC; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -39,7 +39,7 @@ bitflags! { /// `TFD_TIMER_CANCEL_ON_SET` const CANCEL_ON_SET = linux_raw_sys::general::TFD_TIMER_CANCEL_ON_SET; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/vdso.rs b/vendor/rustix/src/backend/linux_raw/vdso.rs index 1b0ae5375..102fa6b38 100644 --- a/vendor/rustix/src/backend/linux_raw/vdso.rs +++ b/vendor/rustix/src/backend/linux_raw/vdso.rs @@ -55,7 +55,7 @@ fn elf_hash(name: &CStr) -> u32 { /// Create a `Vdso` value by parsing the vDSO at the `sysinfo_ehdr` address. fn init_from_sysinfo_ehdr() -> Option<Vdso> { - // SAFETY: the auxv initialization code does extensive checks to ensure + // SAFETY: The auxv initialization code does extensive checks to ensure // that the value we get really is an `AT_SYSINFO_EHDR` value from the // kernel. unsafe { @@ -106,9 +106,9 @@ fn init_from_sysinfo_ehdr() -> Option<Vdso> { vdso.load_end = vdso.base_plus(phdr.p_offset.checked_add(phdr.p_memsz)?)?; vdso.pv_offset = phdr.p_offset.wrapping_sub(phdr.p_vaddr); } else if phdr.p_type == PT_DYNAMIC { - // If `p_offset` is zero, it's more likely that we're looking at memory - // that has been zeroed than that the kernel has somehow aliased the - // `Ehdr` and the `Elf_Dyn` array. + // If `p_offset` is zero, it's more likely that we're looking + // at memory that has been zeroed than that the kernel has + // somehow aliased the `Ehdr` and the `Elf_Dyn` array. if phdr.p_offset < size_of::<Elf_Ehdr>() { return None; } @@ -117,9 +117,9 @@ fn init_from_sysinfo_ehdr() -> Option<Vdso> { .as_ptr(); num_dyn = phdr.p_memsz / size_of::<Elf_Dyn>(); } else if phdr.p_type == PT_INTERP || phdr.p_type == PT_GNU_RELRO { - // Don't trust any ELF image that has an “interpreter” or that uses - // RELRO, which is likely to be a user ELF image rather and not the - // kernel vDSO. + // Don't trust any ELF image that has an “interpreter” or + // that uses RELRO, which is likely to be a user ELF image + // rather and not the kernel vDSO. return None; } } @@ -176,8 +176,8 @@ fn init_from_sysinfo_ehdr() -> Option<Vdso> { } i = i.checked_add(1)?; } - // The upstream code checks `symstrings`, `symtab`, and `hash` for null; - // here, `check_raw_pointer` has already done that. + // The upstream code checks `symstrings`, `symtab`, and `hash` for + // null; here, `check_raw_pointer` has already done that. if vdso.verdef.is_null() { vdso.versym = null(); diff --git a/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs b/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs index 1ff50415b..601dc1855 100644 --- a/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs +++ b/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs @@ -36,8 +36,8 @@ use { #[inline] pub(crate) fn clock_gettime(which_clock: ClockId) -> __kernel_timespec { // SAFETY: `CLOCK_GETTIME` contains either null or the address of a - // function with an ABI like libc `clock_gettime`, and calling it has - // the side effect of writing to the result buffer, and no others. + // function with an ABI like libc `clock_gettime`, and calling it has the + // side effect of writing to the result buffer, and no others. unsafe { let mut result = MaybeUninit::<__kernel_timespec>::uninit(); let callee = match transmute(CLOCK_GETTIME.load(Relaxed)) { @@ -78,8 +78,8 @@ pub(crate) fn clock_gettime_dynamic(which_clock: DynamicClockId<'_>) -> io::Resu }; // SAFETY: `CLOCK_GETTIME` contains either null or the address of a - // function with an ABI like libc `clock_gettime`, and calling it has - // the side effect of writing to the result buffer, and no others. + // function with an ABI like libc `clock_gettime`, and calling it has the + // side effect of writing to the result buffer, and no others. unsafe { const EINVAL: c::c_int = -(c::EINVAL as c::c_int); let mut timespec = MaybeUninit::<Timespec>::uninit(); @@ -234,8 +234,8 @@ pub(super) type SyscallType = unsafe extern "C" fn(); #[cold] fn init_clock_gettime() -> ClockGettimeType { init(); - // SAFETY: Load the function address from static storage that we - // just initialized. + // SAFETY: Load the function address from static storage that we just + // initialized. unsafe { transmute(CLOCK_GETTIME.load(Relaxed)) } } @@ -244,8 +244,8 @@ fn init_clock_gettime() -> ClockGettimeType { #[cold] fn init_syscall() -> SyscallType { init(); - // SAFETY: Load the function address from static storage that we - // just initialized. + // SAFETY: Load the function address from static storage that we just + // initialized. unsafe { transmute(SYSCALL.load(Relaxed)) } } @@ -318,7 +318,7 @@ unsafe fn _rustix_clock_gettime_via_syscall( #[cfg(target_arch = "x86")] extern "C" { /// A symbol pointing to an `int 0x80` instruction. This “function” is only - /// called from assembly, and only with the x86 syscall calling convention. + /// called from assembly, and only with the x86 syscall calling convention, /// so its signature here is not its true signature. /// /// This extern block and the `global_asm!` below can be replaced with @@ -345,9 +345,9 @@ rustix_int_0x80: fn minimal_init() { // SAFETY: Store default function addresses in static storage so that if we - // end up making any system calls while we read the vDSO, they'll work. - // If the memory happens to already be initialized, this is redundant, but - // not harmful. + // end up making any system calls while we read the vDSO, they'll work. If + // the memory happens to already be initialized, this is redundant, but not + // harmful. unsafe { #[cfg(feature = "time")] { @@ -381,9 +381,9 @@ fn init() { if let Some(vdso) = vdso::Vdso::new() { #[cfg(feature = "time")] { - // Look up the platform-specific `clock_gettime` symbol as documented - // [here], except on 32-bit platforms where we look up the - // `64`-suffixed variant and fail if we don't find it. + // Look up the platform-specific `clock_gettime` symbol as + // documented [here], except on 32-bit platforms where we look up + // the `64`-suffixed variant and fail if we don't find it. // // [here]: https://man7.org/linux/man-pages/man7/vdso.7.html #[cfg(target_arch = "x86_64")] @@ -408,8 +408,8 @@ fn init() { #[cfg(target_pointer_width = "64")] let ok = true; - // On some 32-bit platforms, the 64-bit `clock_gettime` symbols are not - // available on older kernel versions. + // On some 32-bit platforms, the 64-bit `clock_gettime` symbols are + // not available on older kernel versions. #[cfg(any( target_arch = "arm", target_arch = "mips", @@ -421,9 +421,9 @@ fn init() { if ok { assert!(!ptr.is_null()); - // SAFETY: Store the computed function addresses in static storage - // so that we don't need to compute it again (but if we do, it - // doesn't hurt anything). + // SAFETY: Store the computed function addresses in static + // storage so that we don't need to compute it again (but if + // we do, it doesn't hurt anything). unsafe { CLOCK_GETTIME.store(ptr.cast(), Relaxed); } diff --git a/vendor/rustix/src/bitcast.rs b/vendor/rustix/src/bitcast.rs index 735101766..77e0e6338 100644 --- a/vendor/rustix/src/bitcast.rs +++ b/vendor/rustix/src/bitcast.rs @@ -1,3 +1,5 @@ +//! The `bitcast` and `bitflags_bits` macros. + #![allow(unused_macros)] // Ensure that the source and destination types are both primitive integer diff --git a/vendor/rustix/src/check_types.rs b/vendor/rustix/src/check_types.rs index bea04e0b7..0140b6d73 100644 --- a/vendor/rustix/src/check_types.rs +++ b/vendor/rustix/src/check_types.rs @@ -19,8 +19,8 @@ macro_rules! check_renamed_type { }; } -/// Check that the field of a struct has the same offset as the -/// corresponding field in the `sys` bindings. +/// Check that the field of a struct has the same offset as the corresponding +/// field in the `sys` bindings. macro_rules! check_struct_field { ($struct:ident, $field:ident) => { const_assert_eq!( @@ -54,8 +54,8 @@ macro_rules! check_struct_renamed_field { }; } -/// The same as `check_struct_renamed_field`, but for when both the struct -/// and a field are renamed. +/// The same as `check_struct_renamed_field`, but for when both the struct and +/// a field are renamed. macro_rules! check_renamed_struct_renamed_field { ($to_struct:ident, $from_struct:ident, $to:ident, $from:ident) => { const_assert_eq!( diff --git a/vendor/rustix/src/clockid.rs b/vendor/rustix/src/clockid.rs index abeeb7095..033444d9c 100644 --- a/vendor/rustix/src/clockid.rs +++ b/vendor/rustix/src/clockid.rs @@ -16,21 +16,31 @@ use crate::fd::BorrowedFd; #[non_exhaustive] pub enum ClockId { /// `CLOCK_REALTIME` - Realtime = c::CLOCK_REALTIME, + Realtime = bitcast!(c::CLOCK_REALTIME), /// `CLOCK_MONOTONIC` - Monotonic = c::CLOCK_MONOTONIC, + Monotonic = bitcast!(c::CLOCK_MONOTONIC), /// `CLOCK_UPTIME` #[cfg(any(freebsdlike, target_os = "openbsd"))] Uptime = c::CLOCK_UPTIME, /// `CLOCK_PROCESS_CPUTIME_ID` - #[cfg(not(any(solarish, target_os = "netbsd", target_os = "redox")))] + #[cfg(not(any( + solarish, + target_os = "netbsd", + target_os = "redox", + target_os = "vita" + )))] ProcessCPUTime = c::CLOCK_PROCESS_CPUTIME_ID, /// `CLOCK_THREAD_CPUTIME_ID` - #[cfg(not(any(solarish, target_os = "netbsd", target_os = "redox")))] + #[cfg(not(any( + solarish, + target_os = "netbsd", + target_os = "redox", + target_os = "vita" + )))] ThreadCPUTime = c::CLOCK_THREAD_CPUTIME_ID, /// `CLOCK_REALTIME_COARSE` diff --git a/vendor/rustix/src/cstr.rs b/vendor/rustix/src/cstr.rs index d32436e18..17a8c8b77 100644 --- a/vendor/rustix/src/cstr.rs +++ b/vendor/rustix/src/cstr.rs @@ -44,8 +44,9 @@ macro_rules! cstr { // call `from_bytes_with_nul_unchecked`, which as of this writing // is defined as `#[inline]` and completely optimizes away. // - // SAFETY: We have manually checked that the string does not contain - // embedded NULs above, and we append or own NUL terminator here. + // SAFETY: We have manually checked that the string does not + // contain embedded NULs above, and we append or own NUL terminator + // here. unsafe { $crate::ffi::CStr::from_bytes_with_nul_unchecked(concat!($str, "\0").as_bytes()) } diff --git a/vendor/rustix/src/event/kqueue.rs b/vendor/rustix/src/event/kqueue.rs index 05ee4d71b..cd996aaea 100644 --- a/vendor/rustix/src/event/kqueue.rs +++ b/vendor/rustix/src/event/kqueue.rs @@ -73,11 +73,11 @@ impl Event { flags: flags.bits() as _, fflags, data: { - // On openbsd, data is an i64 and not an isize + // On OpenBSD, data is an `i64` and not an `isize`. data as _ }, udata: { - // On netbsd, udata is an isize and not a pointer. + // On NetBSD, udata is an `isize` and not a pointer. // TODO: Strict provenance, prevent int-to-ptr cast. udata as _ }, @@ -93,7 +93,7 @@ impl Event { /// Get the user data for this event. pub fn udata(&self) -> isize { - // On netbsd, udata is an isize and not a pointer. + // On NetBSD, udata is an isize and not a pointer. // TODO: Strict provenance, prevent ptr-to-int cast. self.inner.udata as _ @@ -101,7 +101,7 @@ impl Event { /// Get the raw data for this event. pub fn data(&self) -> i64 { - // On some bsds, data is an isize and not an i64 + // On some BSDs, data is an `isize` and not an `i64`. self.inner.data as _ } @@ -263,7 +263,7 @@ bitflags::bitflags! { /// TODO const ERROR = c::EV_ERROR as _; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -294,7 +294,7 @@ bitflags::bitflags! { /// The link count of the file has changed. const LINK = c::NOTE_LINK; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -319,7 +319,7 @@ bitflags::bitflags! { /// An error has occurred with following the process. const TRACKERR = c::NOTE_TRACKERR; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -351,7 +351,7 @@ bitflags::bitflags! { /// Trigger the event. const TRIGGER = c::NOTE_TRIGGER; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/event/mod.rs b/vendor/rustix/src/event/mod.rs index 03abc9f12..b0b62e0a6 100644 --- a/vendor/rustix/src/event/mod.rs +++ b/vendor/rustix/src/event/mod.rs @@ -13,7 +13,7 @@ mod poll; #[cfg(solarish)] pub mod port; -#[cfg(all(feature = "alloc", linux_kernel))] +#[cfg(linux_kernel)] pub use crate::backend::event::epoll; #[cfg(any( linux_kernel, diff --git a/vendor/rustix/src/fs/abs.rs b/vendor/rustix/src/fs/abs.rs index f57bd00fe..8953f351e 100644 --- a/vendor/rustix/src/fs/abs.rs +++ b/vendor/rustix/src/fs/abs.rs @@ -1,7 +1,7 @@ //! POSIX-style filesystem functions which operate on bare paths. use crate::fd::OwnedFd; -#[cfg(not(target_os = "espidf"))] +#[cfg(not(any(target_os = "espidf", target_os = "vita")))] use crate::fs::Access; #[cfg(not(any( solarish, @@ -10,6 +10,7 @@ use crate::fs::Access; target_os = "netbsd", target_os = "nto", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] use crate::fs::StatFs; @@ -129,7 +130,8 @@ fn _readlink(path: &CStr, mut buffer: Vec<u8>) -> io::Result<CString> { buffer.resize(nread, 0_u8); return Ok(CString::new(buffer).unwrap()); } - buffer.reserve(1); // use `Vec` reallocation strategy to grow capacity exponentially + // Use `Vec` reallocation strategy to grow capacity exponentially. + buffer.reserve(1); buffer.resize(buffer.capacity(), 0_u8); } } @@ -235,7 +237,7 @@ pub fn mkdir<P: path::Arg>(path: P, mode: Mode) -> io::Result<()> { /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html /// [Linux]: https://man7.org/linux/man-pages/man2/access.2.html -#[cfg(not(target_os = "espidf"))] +#[cfg(not(any(target_os = "espidf", target_os = "vita")))] #[inline] pub fn access<P: path::Arg>(path: P, access: Access) -> io::Result<()> { path.into_with_c_str(|path| backend::fs::syscalls::access(path, access)) @@ -257,6 +259,7 @@ pub fn access<P: path::Arg>(path: P, access: Access) -> io::Result<()> { target_os = "netbsd", target_os = "nto", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] #[inline] diff --git a/vendor/rustix/src/fs/at.rs b/vendor/rustix/src/fs/at.rs index 0434b56ef..f40c46ce6 100644 --- a/vendor/rustix/src/fs/at.rs +++ b/vendor/rustix/src/fs/at.rs @@ -6,14 +6,18 @@ //! [`cwd`]: crate::fs::CWD use crate::fd::OwnedFd; +#[cfg(not(any(target_os = "espidf", target_os = "vita")))] +use crate::fs::Access; +#[cfg(not(target_os = "espidf"))] +use crate::fs::AtFlags; #[cfg(apple)] use crate::fs::CloneFlags; -#[cfg(not(any(apple, target_os = "espidf", target_os = "wasi")))] -use crate::fs::FileType; #[cfg(linux_kernel)] use crate::fs::RenameFlags; #[cfg(not(any(target_os = "aix", target_os = "espidf")))] use crate::fs::Stat; +#[cfg(not(any(apple, target_os = "espidf", target_os = "vita", target_os = "wasi")))] +use crate::fs::{Dev, FileType}; #[cfg(not(any(target_os = "espidf", target_os = "wasi")))] use crate::fs::{Gid, Uid}; use crate::fs::{Mode, OFlags}; @@ -26,24 +30,19 @@ use { alloc::vec::Vec, backend::fd::BorrowedFd, }; -#[cfg(not(target_os = "espidf"))] -use { - crate::fs::{Access, AtFlags, Timestamps}, - crate::timespec::Nsecs, -}; - -pub use backend::fs::types::{Dev, RawMode}; +#[cfg(not(any(target_os = "espidf", target_os = "vita")))] +use {crate::fs::Timestamps, crate::timespec::Nsecs}; /// `UTIME_NOW` for use with [`utimensat`]. /// /// [`utimensat`]: crate::fs::utimensat -#[cfg(not(any(target_os = "espidf", target_os = "redox")))] +#[cfg(not(any(target_os = "espidf", target_os = "redox", target_os = "vita")))] pub const UTIME_NOW: Nsecs = backend::c::UTIME_NOW as Nsecs; /// `UTIME_OMIT` for use with [`utimensat`]. /// /// [`utimensat`]: crate::fs::utimensat -#[cfg(not(any(target_os = "espidf", target_os = "redox")))] +#[cfg(not(any(target_os = "espidf", target_os = "redox", target_os = "vita")))] pub const UTIME_OMIT: Nsecs = backend::c::UTIME_OMIT as Nsecs; /// `openat(dirfd, path, oflags, mode)`—Opens a file. @@ -104,8 +103,8 @@ fn _readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, mut buffer: Vec<u8>) -> io::R debug_assert!(nread <= buffer.capacity()); if nread < buffer.capacity() { - // SAFETY: From the [documentation]: - // "On success, these calls return the number of bytes placed in buf." + // SAFETY: From the [documentation]: “On success, these calls + // return the number of bytes placed in buf.” // // [documentation]: https://man7.org/linux/man-pages/man2/readlinkat.2.html unsafe { @@ -113,13 +112,13 @@ fn _readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, mut buffer: Vec<u8>) -> io::R } // SAFETY: - // - "readlink places the contents of the symbolic link pathname in the buffer - // buf" - // - [POSIX definition 3.271: Pathname]: "A string that is used to identify a - // file." - // - [POSIX definition 3.375: String]: "A contiguous sequence of bytes - // terminated by and including the first null byte." - // - "readlink does not append a terminating null byte to buf." + // - “readlink places the contents of the symbolic link pathname in + // the buffer buf” + // - [POSIX definition 3.271: Pathname]: “A string that is used to + // identify a file.” + // - [POSIX definition 3.375: String]: “A contiguous sequence of + // bytes terminated by and including the first null byte.” + // - “readlink does not append a terminating null byte to buf.” // // Thus, there will be no NUL bytes in the string. // @@ -130,9 +129,8 @@ fn _readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, mut buffer: Vec<u8>) -> io::R } } - buffer.reserve(buffer.capacity() + 1); // use `Vec` reallocation - // strategy to grow capacity - // exponentially + // Use `Vec` reallocation strategy to grow capacity exponentially. + buffer.reserve(buffer.capacity() + 1); } } @@ -182,8 +180,8 @@ pub fn linkat<P: path::Arg, Q: path::Arg, PFd: AsFd, QFd: AsFd>( /// `unlinkat(fd, path, flags)`—Unlinks a file or remove a directory. /// -/// With the [`REMOVEDIR`] flag, this removes a directory. This is in place -/// of a `rmdirat` function. +/// With the [`REMOVEDIR`] flag, this removes a directory. This is in place of +/// a `rmdirat` function. /// /// # References /// - [POSIX] @@ -314,7 +312,7 @@ pub fn statat<P: path::Arg, Fd: AsFd>(dirfd: Fd, path: P, flags: AtFlags) -> io: /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/faccessat.html /// [Linux]: https://man7.org/linux/man-pages/man2/faccessat.2.html -#[cfg(not(target_os = "espidf"))] +#[cfg(not(any(target_os = "espidf", target_os = "vita")))] #[inline] #[doc(alias = "faccessat")] pub fn accessat<P: path::Arg, Fd: AsFd>( @@ -334,7 +332,7 @@ pub fn accessat<P: path::Arg, Fd: AsFd>( /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/utimensat.html /// [Linux]: https://man7.org/linux/man-pages/man2/utimensat.2.html -#[cfg(not(target_os = "espidf"))] +#[cfg(not(any(target_os = "espidf", target_os = "vita")))] #[inline] pub fn utimensat<P: path::Arg, Fd: AsFd>( dirfd: Fd, @@ -396,7 +394,7 @@ pub fn fclonefileat<Fd: AsFd, DstFd: AsFd, P: path::Arg>( /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/mknodat.html /// [Linux]: https://man7.org/linux/man-pages/man2/mknodat.2.html -#[cfg(not(any(apple, target_os = "espidf", target_os = "wasi")))] +#[cfg(not(any(apple, target_os = "espidf", target_os = "vita", target_os = "wasi")))] #[inline] pub fn mknodat<P: path::Arg, Fd: AsFd>( dirfd: Fd, diff --git a/vendor/rustix/src/fs/constants.rs b/vendor/rustix/src/fs/constants.rs index 85889d90e..a9237af7a 100644 --- a/vendor/rustix/src/fs/constants.rs +++ b/vendor/rustix/src/fs/constants.rs @@ -3,17 +3,5 @@ use crate::backend; pub use crate::io::FdFlags; -#[cfg(not(target_os = "espidf"))] -pub use backend::fs::types::Access; -pub use backend::fs::types::{Dev, Mode, OFlags}; - -#[cfg(not(any(target_os = "espidf", target_os = "redox")))] -pub use backend::fs::types::AtFlags; - -#[cfg(apple)] -pub use backend::fs::types::{CloneFlags, CopyfileFlags}; - -#[cfg(linux_kernel)] -pub use backend::fs::types::*; - pub use crate::timespec::{Nsecs, Secs, Timespec}; +pub use backend::fs::types::*; diff --git a/vendor/rustix/src/fs/fadvise.rs b/vendor/rustix/src/fs/fadvise.rs index 5bc3a588a..a760a186a 100644 --- a/vendor/rustix/src/fs/fadvise.rs +++ b/vendor/rustix/src/fs/fadvise.rs @@ -1,7 +1,6 @@ use crate::{backend, io}; use backend::fd::AsFd; - -pub use backend::fs::types::Advice; +use backend::fs::types::Advice; /// `posix_fadvise(fd, offset, len, advice)`—Declares an expected access /// pattern for a file. diff --git a/vendor/rustix/src/fs/fcntl.rs b/vendor/rustix/src/fs/fcntl.rs index facbc9fa3..f80db849a 100644 --- a/vendor/rustix/src/fs/fcntl.rs +++ b/vendor/rustix/src/fs/fcntl.rs @@ -1,13 +1,14 @@ -//! The Unix `fcntl` function is effectively lots of different functions -//! hidden behind a single dynamic dispatch interface. In order to provide -//! a type-safe API, rustix makes them all separate functions so that they -//! can have dedicated static type signatures. +//! The Unix `fcntl` function is effectively lots of different functions hidden +//! behind a single dynamic dispatch interface. In order to provide a type-safe +//! API, rustix makes them all separate functions so that they can have +//! dedicated static type signatures. #[cfg(not(any( target_os = "emscripten", target_os = "espidf", target_os = "fuchsia", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] use crate::fs::FlockOperation; @@ -64,7 +65,7 @@ pub fn fcntl_get_seals<Fd: AsFd>(fd: Fd) -> io::Result<SealFlags> { } #[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))] -pub use backend::fs::types::SealFlags; +use backend::fs::types::SealFlags; /// `fcntl(fd, F_ADD_SEALS)` /// @@ -86,8 +87,8 @@ pub fn fcntl_add_seals<Fd: AsFd>(fd: Fd, seals: SealFlags) -> io::Result<()> { /// file should be locked. /// /// Unlike `flock`-style locks, `fcntl`-style locks are process-associated, -/// meaning that they don't guard against being acquired by two threads in -/// the same process. +/// meaning that they don't guard against being acquired by two threads in the +/// same process. /// /// # References /// - [POSIX] @@ -100,6 +101,7 @@ pub fn fcntl_add_seals<Fd: AsFd>(fd: Fd, seals: SealFlags) -> io::Result<()> { target_os = "espidf", target_os = "fuchsia", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] #[inline] diff --git a/vendor/rustix/src/fs/fcopyfile.rs b/vendor/rustix/src/fs/fcopyfile.rs index d8931733f..e8f26ffdc 100644 --- a/vendor/rustix/src/fs/fcopyfile.rs +++ b/vendor/rustix/src/fs/fcopyfile.rs @@ -1,9 +1,7 @@ use crate::fs::CopyfileFlags; use crate::{backend, io}; use backend::fd::AsFd; - -/// `copyfile_state_t` -pub use backend::fs::types::copyfile_state_t; +use backend::fs::types::copyfile_state_t; /// `fcopyfile(from, to, state, flags)` /// diff --git a/vendor/rustix/src/fs/fd.rs b/vendor/rustix/src/fs/fd.rs index 94de43daa..3ef4b3826 100644 --- a/vendor/rustix/src/fs/fd.rs +++ b/vendor/rustix/src/fs/fd.rs @@ -7,10 +7,6 @@ use crate::fs::{Gid, Uid}; use crate::fs::{OFlags, SeekFrom, Timespec}; use crate::{backend, io}; use backend::fd::{AsFd, BorrowedFd}; - -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -pub use backend::fs::types::FlockOperation; - #[cfg(not(any( netbsdlike, solarish, @@ -19,11 +15,19 @@ pub use backend::fs::types::FlockOperation; target_os = "espidf", target_os = "nto", target_os = "redox", + target_os = "vita", )))] -pub use backend::fs::types::FallocateFlags; - -pub use backend::fs::types::Stat; - +use backend::fs::types::FallocateFlags; +#[cfg(not(any( + target_os = "espidf", + target_os = "solaris", + target_os = "vita", + target_os = "wasi" +)))] +use backend::fs::types::FlockOperation; +#[cfg(linux_kernel)] +use backend::fs::types::FsWord; +use backend::fs::types::Stat; #[cfg(not(any( solarish, target_os = "espidf", @@ -31,15 +35,12 @@ pub use backend::fs::types::Stat; target_os = "netbsd", target_os = "nto", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] -pub use backend::fs::types::StatFs; - +use backend::fs::types::StatFs; #[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -pub use backend::fs::types::{StatVfs, StatVfsMountFlags}; - -#[cfg(linux_kernel)] -pub use backend::fs::types::FsWord; +use backend::fs::types::StatVfs; /// Timestamps used by [`utimensat`] and [`futimens`]. /// @@ -107,8 +108,8 @@ pub fn tell<Fd: AsFd>(fd: Fd) -> io::Result<u64> { /// `fchmod(fd, mode)`—Sets open file or directory permissions. /// -/// This implementation does not support `O_PATH` file descriptors, even on -/// platforms where the host libc emulates it. +/// This implementation does not support [`OFlags::PATH`] file descriptors, +/// even on platforms where the host libc emulates it. /// /// # References /// - [POSIX] @@ -170,6 +171,7 @@ pub fn fstat<Fd: AsFd>(fd: Fd) -> io::Result<Stat> { target_os = "netbsd", target_os = "nto", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] #[inline] @@ -205,7 +207,7 @@ pub fn fstatvfs<Fd: AsFd>(fd: Fd) -> io::Result<StatVfs> { /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html /// [Linux]: https://man7.org/linux/man-pages/man2/utimensat.2.html -#[cfg(not(target_os = "espidf"))] +#[cfg(not(any(target_os = "espidf", target_os = "vita")))] #[inline] pub fn futimens<Fd: AsFd>(fd: Fd, times: &Timestamps) -> io::Result<()> { backend::fs::syscalls::futimens(fd.as_fd(), times) @@ -234,6 +236,7 @@ pub fn futimens<Fd: AsFd>(fd: Fd, times: &Timestamps) -> io::Result<()> { target_os = "espidf", target_os = "nto", target_os = "redox", + target_os = "vita", )))] // not implemented in libc for netbsd yet #[inline] #[doc(alias = "posix_fallocate")] @@ -304,6 +307,7 @@ pub fn fsync<Fd: AsFd>(fd: Fd) -> io::Result<()> { target_os = "espidf", target_os = "haiku", target_os = "redox", + target_os = "vita", )))] #[inline] pub fn fdatasync<Fd: AsFd>(fd: Fd) -> io::Result<()> { @@ -329,7 +333,12 @@ pub fn ftruncate<Fd: AsFd>(fd: Fd, length: u64) -> io::Result<()> { /// - [Linux] /// /// [Linux]: https://man7.org/linux/man-pages/man2/flock.2.html -#[cfg(not(any(target_os = "espidf", target_os = "solaris", target_os = "wasi")))] +#[cfg(not(any( + target_os = "espidf", + target_os = "solaris", + target_os = "vita", + target_os = "wasi" +)))] #[inline] pub fn flock<Fd: AsFd>(fd: Fd, operation: FlockOperation) -> io::Result<()> { backend::fs::syscalls::flock(fd.as_fd(), operation) diff --git a/vendor/rustix/src/fs/file_type.rs b/vendor/rustix/src/fs/file_type.rs deleted file mode 100644 index cf8fc1d38..000000000 --- a/vendor/rustix/src/fs/file_type.rs +++ /dev/null @@ -1,4 +0,0 @@ -use crate::backend; - -/// `S_IF*` constants. -pub use backend::fs::types::FileType; diff --git a/vendor/rustix/src/fs/memfd_create.rs b/vendor/rustix/src/fs/memfd_create.rs index bbcbab258..83d1ff51e 100644 --- a/vendor/rustix/src/fs/memfd_create.rs +++ b/vendor/rustix/src/fs/memfd_create.rs @@ -1,7 +1,6 @@ use crate::fd::OwnedFd; use crate::{backend, io, path}; - -pub use backend::fs::types::MemfdFlags; +use backend::fs::types::MemfdFlags; /// `memfd_create(path, flags)` /// diff --git a/vendor/rustix/src/fs/mod.rs b/vendor/rustix/src/fs/mod.rs index 1ea0d1351..f6d543a98 100644 --- a/vendor/rustix/src/fs/mod.rs +++ b/vendor/rustix/src/fs/mod.rs @@ -19,6 +19,7 @@ mod dir; target_os = "espidf", target_os = "haiku", target_os = "redox", + target_os = "vita", )))] mod fadvise; pub(crate) mod fcntl; @@ -27,17 +28,17 @@ mod fcntl_apple; #[cfg(apple)] mod fcopyfile; pub(crate) mod fd; -mod file_type; #[cfg(apple)] mod getpath; #[cfg(not(target_os = "wasi"))] // WASI doesn't have get[gpu]id. mod id; -#[cfg(not(target_os = "wasi"))] +#[cfg(linux_kernel)] mod ioctl; #[cfg(not(any( target_os = "espidf", target_os = "haiku", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] mod makedev; @@ -55,7 +56,12 @@ mod seek_from; mod sendfile; #[cfg(linux_kernel)] mod statx; -#[cfg(not(any(target_os = "espidf", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any( + target_os = "espidf", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] mod sync; #[cfg(any(apple, linux_kernel))] mod xattr; @@ -81,30 +87,31 @@ pub use dir::{Dir, DirEntry}; target_os = "espidf", target_os = "haiku", target_os = "redox", + target_os = "vita", )))] -pub use fadvise::{fadvise, Advice}; +pub use fadvise::fadvise; pub use fcntl::*; #[cfg(apple)] pub use fcntl_apple::*; #[cfg(apple)] pub use fcopyfile::*; pub use fd::*; -pub use file_type::FileType; #[cfg(apple)] pub use getpath::getpath; #[cfg(not(target_os = "wasi"))] pub use id::*; -#[cfg(not(target_os = "wasi"))] +#[cfg(linux_kernel)] pub use ioctl::*; #[cfg(not(any( target_os = "espidf", target_os = "haiku", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] pub use makedev::*; #[cfg(any(linux_kernel, target_os = "freebsd"))] -pub use memfd_create::{memfd_create, MemfdFlags}; +pub use memfd_create::memfd_create; #[cfg(linux_kernel)] #[cfg(feature = "fs")] pub use mount::*; @@ -116,8 +123,13 @@ pub use seek_from::SeekFrom; #[cfg(target_os = "linux")] pub use sendfile::sendfile; #[cfg(linux_kernel)] -pub use statx::{statx, Statx, StatxFlags, StatxTimestamp}; -#[cfg(not(any(target_os = "espidf", target_os = "redox", target_os = "wasi")))] +pub use statx::statx; +#[cfg(not(any( + target_os = "espidf", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] pub use sync::sync; #[cfg(any(apple, linux_kernel))] pub use xattr::*; diff --git a/vendor/rustix/src/fs/mount.rs b/vendor/rustix/src/fs/mount.rs index 0f04b7f69..bd44aaa7d 100644 --- a/vendor/rustix/src/fs/mount.rs +++ b/vendor/rustix/src/fs/mount.rs @@ -2,16 +2,16 @@ //! //! These have been moved to a new `rustix::mount` module. -#[deprecated(note = "rustix::fs::UnmountFlags` moved to `rustix::mount::UnmountFlags`.")] +#[deprecated(note = "`rustix::fs::UnmountFlags` moved to `rustix::mount::UnmountFlags`.")] #[doc(hidden)] pub use crate::mount::UnmountFlags; -#[deprecated(note = "rustix::fs::MountFlags` moved to `rustix::mount::MountFlags`.")] +#[deprecated(note = "`rustix::fs::MountFlags` moved to `rustix::mount::MountFlags`.")] #[doc(hidden)] pub use crate::mount::MountFlags; #[deprecated( - note = "rustix::fs::MountPropagationFlags` moved to `rustix::mount::MountPropagationFlags`." + note = "`rustix::fs::MountPropagationFlags` moved to `rustix::mount::MountPropagationFlags`." )] #[doc(hidden)] pub use crate::mount::MountPropagationFlags; diff --git a/vendor/rustix/src/fs/raw_dir.rs b/vendor/rustix/src/fs/raw_dir.rs index fd8aefa3a..93686b19a 100644 --- a/vendor/rustix/src/fs/raw_dir.rs +++ b/vendor/rustix/src/fs/raw_dir.rs @@ -43,10 +43,11 @@ impl<'buf, Fd: AsFd> RawDir<'buf, Fd> { /// ``` /// # use std::mem::MaybeUninit; /// # use rustix::fs::{CWD, Mode, OFlags, openat, RawDir}; + /// # use rustix::cstr; /// /// let fd = openat( /// CWD, - /// ".", + /// cstr!("."), /// OFlags::RDONLY | OFlags::DIRECTORY | OFlags::CLOEXEC, /// Mode::empty(), /// ) @@ -65,10 +66,11 @@ impl<'buf, Fd: AsFd> RawDir<'buf, Fd> { /// ``` /// # use std::mem::MaybeUninit; /// # use rustix::fs::{CWD, Mode, OFlags, openat, RawDir}; + /// # use rustix::cstr; /// /// let fd = openat( /// CWD, - /// ".", + /// cstr!("."), /// OFlags::RDONLY | OFlags::DIRECTORY | OFlags::CLOEXEC, /// Mode::empty(), /// ) @@ -92,10 +94,11 @@ impl<'buf, Fd: AsFd> RawDir<'buf, Fd> { /// # use std::mem::MaybeUninit; /// # use rustix::fs::{CWD, Mode, OFlags, openat, RawDir}; /// # use rustix::io::Errno; + /// # use rustix::cstr; /// /// let fd = openat( /// CWD, - /// ".", + /// cstr!("."), /// OFlags::RDONLY | OFlags::DIRECTORY | OFlags::CLOEXEC, /// Mode::empty(), /// ) diff --git a/vendor/rustix/src/fs/statx.rs b/vendor/rustix/src/fs/statx.rs index 1791697af..b7d6787a6 100644 --- a/vendor/rustix/src/fs/statx.rs +++ b/vendor/rustix/src/fs/statx.rs @@ -3,8 +3,7 @@ use crate::fd::AsFd; use crate::fs::AtFlags; use crate::{backend, io, path}; - -pub use backend::fs::types::{Statx, StatxFlags, StatxTimestamp}; +use backend::fs::types::{Statx, StatxFlags}; #[cfg(feature = "linux_4_11")] use backend::fs::syscalls::statx as _statx; @@ -28,8 +27,9 @@ use compat::statx as _statx; /// # use std::io; /// # use rustix::fs::{AtFlags, StatxFlags}; /// # use rustix::fd::BorrowedFd; -/// /// Try to determine if the provided path is a mount root. Will return `Ok(None)` if -/// /// the kernel is not new enough to support statx() or [`libc::STATX_ATTR_MOUNT_ROOT`]. +/// /// Try to determine if the provided path is a mount root. Will return +/// /// `Ok(None)` if the kernel is not new enough to support `statx` or +/// /// [`libc::STATX_ATTR_MOUNT_ROOT`]. /// fn is_mountpoint(root: BorrowedFd<'_>, path: &Path) -> io::Result<Option<bool>> { /// use rustix::fs::{AtFlags, StatxFlags}; /// @@ -71,8 +71,9 @@ mod compat { use backend::fs::types::{Statx, StatxFlags}; - // Linux kernel prior to 4.11 old versions of Docker don't support `statx`. - // We store the availability in a global to avoid unnecessary syscalls. + // Linux kernel prior to 4.11 and old versions of Docker don't support + // `statx`. We store the availability in a global to avoid unnecessary + // syscalls. // // 0: Unknown // 1: Not available diff --git a/vendor/rustix/src/fs/xattr.rs b/vendor/rustix/src/fs/xattr.rs index 53612f71f..d5be7a34b 100644 --- a/vendor/rustix/src/fs/xattr.rs +++ b/vendor/rustix/src/fs/xattr.rs @@ -15,7 +15,7 @@ bitflags! { /// `XATTR_REPLACE` const REPLACE = c::XATTR_REPLACE as c::c_uint; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/io/dup.rs b/vendor/rustix/src/io/dup.rs index 9f5186192..46fb38ad3 100644 --- a/vendor/rustix/src/io/dup.rs +++ b/vendor/rustix/src/io/dup.rs @@ -115,6 +115,7 @@ pub fn dup2<Fd: AsFd>(fd: Fd, new: &mut OwnedFd) -> io::Result<()> { target_os = "aix", target_os = "espidf", target_os = "nto", + target_os = "vita", target_os = "wasi" )))] #[inline] diff --git a/vendor/rustix/src/io/fcntl.rs b/vendor/rustix/src/io/fcntl.rs index 913e9d062..1880ac7db 100644 --- a/vendor/rustix/src/io/fcntl.rs +++ b/vendor/rustix/src/io/fcntl.rs @@ -1,10 +1,10 @@ -//! The Unix `fcntl` function is effectively lots of different functions -//! hidden behind a single dynamic dispatch interface. In order to provide -//! a type-safe API, rustix makes them all separate functions so that they -//! can have dedicated static type signatures. +//! The Unix `fcntl` function is effectively lots of different functions hidden +//! behind a single dynamic dispatch interface. In order to provide a type-safe +//! API, rustix makes them all separate functions so that they can have +//! dedicated static type signatures. //! -//! `fcntl` functions which are not specific to files or directories live -//! in the [`io`] module instead. +//! `fcntl` functions which are not specific to files or directories live in +//! the [`io`] module instead. //! //! [`io`]: crate::io diff --git a/vendor/rustix/src/io/ioctl.rs b/vendor/rustix/src/io/ioctl.rs index e85719a4d..f89160bf3 100644 --- a/vendor/rustix/src/io/ioctl.rs +++ b/vendor/rustix/src/io/ioctl.rs @@ -14,16 +14,8 @@ use backend::fd::AsFd; /// `ioctl(fd, FIOCLEX, NULL)`—Set the close-on-exec flag. /// -/// Also known as `fcntl(fd, F_SETFD, FD_CLOEXEC)`. -/// -/// # References -/// - [Winsock2] -/// - [NetBSD] -/// - [OpenBSD] -/// -/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-ioctlsocket -/// [NetBSD]: https://man.netbsd.org/ioctl.2#GENERIC%20IOCTLS -/// [OpenBSD]: https://man.openbsd.org/ioctl.2#GENERIC_IOCTLS +/// This is similar to `fcntl(fd, F_SETFD, FD_CLOEXEC)`, except that it avoids +/// clearing any other flags that might be set. #[cfg(apple)] #[inline] #[doc(alias = "FIOCLEX")] @@ -58,8 +50,8 @@ pub fn ioctl_fionbio<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { /// `ioctl(fd, FIONREAD)`—Returns the number of bytes ready to be read. /// -/// The result of this function gets silently coerced into a C `int` -/// by the OS, so it may contain a wrapped value. +/// The result of this function gets silently coerced into a C `int` by the OS, +/// so it may contain a wrapped value. /// /// # References /// - [Linux] @@ -73,7 +65,7 @@ pub fn ioctl_fionbio<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=ioctl&sektion=2#GENERIC%09IOCTLS /// [NetBSD]: https://man.netbsd.org/ioctl.2#GENERIC%20IOCTLS /// [OpenBSD]: https://man.openbsd.org/ioctl.2#GENERIC_IOCTLS -#[cfg(not(target_os = "espidf"))] +#[cfg(not(any(target_os = "espidf", target_os = "vita")))] #[inline] #[doc(alias = "FIONREAD")] pub fn ioctl_fionread<Fd: AsFd>(fd: Fd) -> io::Result<u64> { diff --git a/vendor/rustix/src/io/read_write.rs b/vendor/rustix/src/io/read_write.rs index 91a28bc39..fe454adba 100644 --- a/vendor/rustix/src/io/read_write.rs +++ b/vendor/rustix/src/io/read_write.rs @@ -192,7 +192,8 @@ pub fn writev<Fd: AsFd>(fd: Fd, bufs: &[IoSlice<'_>]) -> io::Result<usize> { target_os = "haiku", target_os = "nto", target_os = "redox", - target_os = "solaris" + target_os = "solaris", + target_os = "vita" )))] #[inline] pub fn preadv<Fd: AsFd>(fd: Fd, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> { @@ -225,7 +226,8 @@ pub fn preadv<Fd: AsFd>(fd: Fd, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io: target_os = "haiku", target_os = "nto", target_os = "redox", - target_os = "solaris" + target_os = "solaris", + target_os = "vita" )))] #[inline] pub fn pwritev<Fd: AsFd>(fd: Fd, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> { diff --git a/vendor/rustix/src/io_uring.rs b/vendor/rustix/src/io_uring.rs index 09a4d6d62..83941922c 100644 --- a/vendor/rustix/src/io_uring.rs +++ b/vendor/rustix/src/io_uring.rs @@ -31,6 +31,49 @@ use core::mem::MaybeUninit; use core::ptr::{null_mut, write_bytes}; use linux_raw_sys::net; +// Export types used in io_uring APIs. +pub use crate::event::epoll::{ + Event as EpollEvent, EventData as EpollEventData, EventFlags as EpollEventFlags, +}; +pub use crate::fs::{Advice, AtFlags, Mode, OFlags, RenameFlags, ResolveFlags, Statx, StatxFlags}; +pub use crate::io::ReadWriteFlags; +pub use crate::net::{RecvFlags, SendFlags, SocketFlags}; +pub use crate::timespec::Timespec; +pub use linux_raw_sys::general::sigset_t; + +pub use net::{__kernel_sockaddr_storage as sockaddr_storage, msghdr, sockaddr, socklen_t}; + +// Declare the `c_char` type for use with entries that take pointers +// to C strings. Define it as unsigned or signed according to the platform +// so that we match what Rust's `CStr` uses. +// +// When we can update to linux-raw-sys 0.5, we can remove this, as its +// `c_char` type will declare this. +/// The C `char` type. +#[cfg(any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "msp430", + target_arch = "powerpc", + target_arch = "powerpc64", + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "s390x", +))] +#[allow(non_camel_case_types)] +pub type c_char = u8; +/// The C `char` type. +#[cfg(any( + target_arch = "mips", + target_arch = "mips64", + target_arch = "sparc64", + target_arch = "x86", + target_arch = "x86_64", + target_arch = "xtensa", +))] +#[allow(non_camel_case_types)] +pub type c_char = i8; + mod sys { pub(super) use linux_raw_sys::io_uring::*; #[cfg(test)] @@ -124,7 +167,7 @@ bitflags::bitflags! { /// `IORING_ENTER_REGISTERED_RING` const REGISTERED_RING = sys::IORING_ENTER_REGISTERED_RING; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -462,7 +505,7 @@ bitflags::bitflags! { /// `IORING_SETUP_DEFER_TASKRUN` const DEFER_TASKRUN = sys::IORING_SETUP_DEFER_TASKRUN; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -493,7 +536,7 @@ bitflags::bitflags! { /// `1 << IOSQE_CQE_SKIP_SUCCESS_BIT` const CQE_SKIP_SUCCESS = 1 << sys::IOSQE_CQE_SKIP_SUCCESS_BIT as u8; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -515,7 +558,7 @@ bitflags::bitflags! { /// `IORING_CQE_F_NOTIF` const NOTIF = bitcast!(sys::IORING_CQE_F_NOTIF); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -528,7 +571,7 @@ bitflags::bitflags! { /// `IORING_FSYNC_DATASYNC` const DATASYNC = sys::IORING_FSYNC_DATASYNC; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -563,7 +606,7 @@ bitflags::bitflags! { /// `IORING_LINK_TIMEOUT_UPDATE` const LINK_TIMEOUT_UPDATE = sys::IORING_LINK_TIMEOUT_UPDATE; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -576,7 +619,7 @@ bitflags::bitflags! { /// `SPLICE_F_FD_IN_FIXED` const FD_IN_FIXED = sys::SPLICE_F_FD_IN_FIXED; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -589,7 +632,7 @@ bitflags::bitflags! { /// `IORING_MSG_RING_CQE_SKIP` const CQE_SKIP = sys::IORING_MSG_RING_CQE_SKIP; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -611,7 +654,7 @@ bitflags::bitflags! { /// `IORING_ASYNC_CANCEL_FD` const FD_FIXED = sys::IORING_ASYNC_CANCEL_FD_FIXED; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -660,7 +703,7 @@ bitflags::bitflags! { /// `IORING_FEAT_LINKED_FILE` const LINKED_FILE = sys::IORING_FEAT_LINKED_FILE; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -673,7 +716,7 @@ bitflags::bitflags! { /// `IO_URING_OP_SUPPORTED` const SUPPORTED = sys::IO_URING_OP_SUPPORTED as _; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -686,7 +729,7 @@ bitflags::bitflags! { /// `IORING_RSRC_REGISTER_SPARSE` const REGISTER_SPARSE = sys::IORING_RSRC_REGISTER_SPARSE as _; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -705,7 +748,7 @@ bitflags::bitflags! { /// `IORING_SQ_TASKRUN` const TASKRUN = sys::IORING_SQ_TASKRUN; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -718,7 +761,7 @@ bitflags::bitflags! { /// `IORING_CQ_EVENTFD_DISABLED` const EVENTFD_DISABLED = sys::IORING_CQ_EVENTFD_DISABLED; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -740,7 +783,7 @@ bitflags::bitflags! { /// `IORING_POLL_ADD_LEVEL` const ADD_LEVEL = sys::IORING_POLL_ADD_LEVEL; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -763,7 +806,7 @@ bitflags::bitflags! { /// `IORING_SEND_ZC_REPORT_USAGE` (since Linux 6.2) const ZC_REPORT_USAGE = sys::IORING_SEND_ZC_REPORT_USAGE as _; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -786,7 +829,7 @@ bitflags::bitflags! { /// See also [`IoringSendFlags::FIXED_BUF`]. const FIXED_BUF = sys::IORING_RECVSEND_FIXED_BUF as _; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -799,7 +842,7 @@ bitflags::bitflags! { /// `IORING_ACCEPT_MULTISHOT` const MULTISHOT = sys::IORING_ACCEPT_MULTISHOT as _; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -824,7 +867,7 @@ bitflags::bitflags! { /// `MSG_ERRQUEUE` const ERRQUEUE = net::MSG_ERRQUEUE; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -1062,20 +1105,20 @@ pub union op_flags_union { pub sync_range_flags: u32, /// `msg_flags` is split into `send_flags` and `recv_flags`. #[doc(alias = "msg_flags")] - pub send_flags: crate::net::SendFlags, + pub send_flags: SendFlags, /// `msg_flags` is split into `send_flags` and `recv_flags`. #[doc(alias = "msg_flags")] - pub recv_flags: crate::net::RecvFlags, + pub recv_flags: RecvFlags, pub timeout_flags: IoringTimeoutFlags, - pub accept_flags: crate::net::SocketFlags, + pub accept_flags: SocketFlags, pub cancel_flags: IoringAsyncCancelFlags, - pub open_flags: crate::fs::OFlags, - pub statx_flags: crate::fs::AtFlags, - pub fadvise_advice: crate::fs::Advice, + pub open_flags: OFlags, + pub statx_flags: AtFlags, + pub fadvise_advice: Advice, pub splice_flags: SpliceFlags, - pub rename_flags: crate::fs::RenameFlags, - pub unlink_flags: crate::fs::AtFlags, - pub hardlink_flags: crate::fs::AtFlags, + pub rename_flags: RenameFlags, + pub unlink_flags: AtFlags, + pub hardlink_flags: AtFlags, pub msg_ring_flags: IoringMsgringFlags, } @@ -1087,12 +1130,33 @@ pub union buf_union { pub buf_group: u16, } +// TODO: Rename this to include `addr_len` when we have a semver bump? #[allow(missing_docs)] #[repr(C)] #[derive(Copy, Clone)] pub union splice_fd_in_or_file_index_union { pub splice_fd_in: i32, pub file_index: u32, + pub addr_len: addr_len_struct, +} + +#[allow(missing_docs)] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct addr_len_struct { + pub addr_len: u16, + pub __pad3: [u16; 1], +} + +#[allow(missing_docs)] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct io_uring_sync_cancel_reg { + pub addr: u64, + pub fd: i32, + pub flags: IoringAsyncCancelFlags, + pub timeout: Timespec, + pub pad: [u64; 4], } /// An io_uring Completion Queue Entry. @@ -1269,16 +1333,12 @@ pub struct iovec { #[derive(Debug, Copy, Clone, Default)] pub struct open_how { /// An [`OFlags`] value represented as a `u64`. - /// - /// [`OFlags`]: crate::fs::OFlags pub flags: u64, /// A [`Mode`] value represented as a `u64`. - /// - /// [`Mode`]: crate::fs::Mode pub mode: u64, - pub resolve: crate::fs::ResolveFlags, + pub resolve: ResolveFlags, } #[allow(missing_docs)] @@ -1371,12 +1431,15 @@ impl Default for register_or_sqe_op_or_sqe_flags_union { fn io_uring_layouts() { use sys as c; + assert_eq_size!(io_uring_ptr, u64); + check_renamed_type!(off_or_addr2_union, io_uring_sqe__bindgen_ty_1); check_renamed_type!(addr_or_splice_off_in_union, io_uring_sqe__bindgen_ty_2); check_renamed_type!(addr3_or_cmd_union, io_uring_sqe__bindgen_ty_6); check_renamed_type!(op_flags_union, io_uring_sqe__bindgen_ty_3); check_renamed_type!(buf_union, io_uring_sqe__bindgen_ty_4); check_renamed_type!(splice_fd_in_or_file_index_union, io_uring_sqe__bindgen_ty_5); + check_renamed_type!(addr_len_struct, io_uring_sqe__bindgen_ty_5__bindgen_ty_1); check_renamed_type!( register_or_sqe_op_or_sqe_flags_union, io_uring_restriction__bindgen_ty_1 @@ -1460,4 +1523,5 @@ fn io_uring_layouts() { check_struct!(open_how, flags, mode, resolve); check_struct!(io_uring_buf_reg, ring_addr, ring_entries, bgid, pad, resv); check_struct!(io_uring_buf, addr, len, bid, resv); + check_struct!(io_uring_sync_cancel_reg, addr, fd, flags, timeout, pad); } diff --git a/vendor/rustix/src/ioctl/linux.rs b/vendor/rustix/src/ioctl/linux.rs index 9dc278656..2f3599fc2 100644 --- a/vendor/rustix/src/ioctl/linux.rs +++ b/vendor/rustix/src/ioctl/linux.rs @@ -10,9 +10,9 @@ pub(super) const fn compose_opcode( num: RawOpcode, size: RawOpcode, ) -> RawOpcode { - macro_rules! shift_and_mask { + macro_rules! mask_and_shift { ($val:expr, $shift:expr, $mask:expr) => {{ - ($val << $shift) & $mask + ($val & $mask) << $shift }}; } @@ -23,10 +23,10 @@ pub(super) const fn compose_opcode( Direction::ReadWrite => READ | WRITE, }; - shift_and_mask!(group, GROUP_SHIFT, GROUP_MASK) - | shift_and_mask!(num, NUM_SHIFT, NUM_MASK) - | shift_and_mask!(size, SIZE_SHIFT, SIZE_MASK) - | shift_and_mask!(dir, DIR_SHIFT, DIR_MASK) + mask_and_shift!(group, GROUP_SHIFT, GROUP_MASK) + | mask_and_shift!(num, NUM_SHIFT, NUM_MASK) + | mask_and_shift!(size, SIZE_SHIFT, SIZE_MASK) + | mask_and_shift!(dir, DIR_SHIFT, DIR_MASK) } const NUM_BITS: RawOpcode = 8; @@ -50,7 +50,8 @@ const DIR_MASK: RawOpcode = (1 << DIR_BITS) - 1; target_arch = "aarch64", target_arch = "riscv32", target_arch = "riscv64", - target_arch = "loongarch64" + target_arch = "loongarch64", + target_arch = "csky" ))] mod consts { use super::RawOpcode; @@ -81,3 +82,37 @@ mod consts { pub(super) const SIZE_BITS: RawOpcode = 13; pub(super) const DIR_BITS: RawOpcode = 3; } + +#[cfg(not(any( + // These have no ioctl opcodes defined in linux_raw_sys + // so can't use that as a known-good value for this test. + target_arch = "sparc", + target_arch = "sparc64" +)))] +#[test] +fn check_known_opcodes() { + use crate::backend::c::{c_long, c_uint}; + use core::mem::size_of; + + // _IOR('U', 15, unsigned int) + assert_eq!( + compose_opcode( + Direction::Read, + b'U' as RawOpcode, + 15, + size_of::<c_uint>() as RawOpcode + ), + linux_raw_sys::ioctl::USBDEVFS_CLAIMINTERFACE as RawOpcode + ); + + // _IOW('v', 2, long) + assert_eq!( + compose_opcode( + Direction::Write, + b'v' as RawOpcode, + 2, + size_of::<c_long>() as RawOpcode + ), + linux_raw_sys::ioctl::FS_IOC_SETVERSION as RawOpcode + ); +} diff --git a/vendor/rustix/src/ioctl/mod.rs b/vendor/rustix/src/ioctl/mod.rs index bf2215ab6..ce62d75c4 100644 --- a/vendor/rustix/src/ioctl/mod.rs +++ b/vendor/rustix/src/ioctl/mod.rs @@ -46,13 +46,16 @@ use bsd as platform; /// controlling their behavior, some of which are proprietary. /// /// This crate exposes many other `ioctl` interfaces with safe and idiomatic -/// wrappers, like [`ioctl_fionbio`](crate::io::ioctl_fionbio) and -/// [`ioctl_fionread`](crate::io::ioctl_fionread). It is recommended to use -/// those instead of this function, as they are safer and more idiomatic. -/// For other cases, implement the [`Ioctl`] API and pass it to this function. +/// wrappers, like [`ioctl_fionbio`] and [`ioctl_fionread`]. It is recommended +/// to use those instead of this function, as they are safer and more +/// idiomatic. For other cases, implement the [`Ioctl`] API and pass it to this +/// function. /// /// See documentation for [`Ioctl`] for more information. /// +/// [`ioctl_fionbio`]: crate::io::ioctl_fionbio +/// [`ioctl_fionread`]: crate::io::ioctl_fionread +/// /// # Safety /// /// While [`Ioctl`] takes much of the unsafety out of `ioctl` calls, it is @@ -86,16 +89,16 @@ pub unsafe fn ioctl<F: AsFd, I: Ioctl>(fd: F, mut ioctl: I) -> Result<I::Output> let request = I::OPCODE.raw(); let arg = ioctl.as_ptr(); - // SAFETY: The variant of `Ioctl` asserts that this is a valid IOCTL call to - // make. + // SAFETY: The variant of `Ioctl` asserts that this is a valid IOCTL call + // to make. let output = if I::IS_MUTATING { _ioctl(fd, request, arg)? } else { _ioctl_readonly(fd, request, arg)? }; - // SAFETY: The variant of `Ioctl` asserts that this is a valid pointer to the - // output data. + // SAFETY: The variant of `Ioctl` asserts that this is a valid pointer to + // the output data. I::output_from_ptr(output, arg) } @@ -204,7 +207,9 @@ impl Opcode { Self { raw } } - /// Create a new opcode from a direction, group, number and size. + /// Create a new opcode from a direction, group, number, and size. + /// + /// This corresponds to the C macro `_IOC(direction, group, number, size)` #[cfg(any(linux_kernel, bsd))] #[inline] pub const fn from_components( @@ -225,8 +230,11 @@ impl Opcode { )) } - /// Create a new non-mutating opcode from a group, a number and the type of - /// data. + /// Create a new non-mutating opcode from a group, a number, and the type + /// of data. + /// + /// This corresponds to the C macro `_IO(group, number)` when `T` is zero + /// sized. #[cfg(any(linux_kernel, bsd))] #[inline] pub const fn none<T>(group: u8, number: u8) -> Self { @@ -235,6 +243,8 @@ impl Opcode { /// Create a new reading opcode from a group, a number and the type of /// data. + /// + /// This corresponds to the C macro `_IOR(group, number, T)`. #[cfg(any(linux_kernel, bsd))] #[inline] pub const fn read<T>(group: u8, number: u8) -> Self { @@ -243,6 +253,8 @@ impl Opcode { /// Create a new writing opcode from a group, a number and the type of /// data. + /// + /// This corresponds to the C macro `_IOW(group, number, T)`. #[cfg(any(linux_kernel, bsd))] #[inline] pub const fn write<T>(group: u8, number: u8) -> Self { @@ -251,6 +263,8 @@ impl Opcode { /// Create a new reading and writing opcode from a group, a number and the /// type of data. + /// + /// This corresponds to the C macro `_IOWR(group, number, T)`. #[cfg(any(linux_kernel, bsd))] #[inline] pub const fn read_write<T>(group: u8, number: u8) -> Self { @@ -314,8 +328,14 @@ type _RawOpcode = c::c_int; #[cfg(all(not(linux_raw), target_os = "android"))] type _RawOpcode = c::c_int; -// BSD, Haiku, and Redox use `unsigned long`. -#[cfg(any(bsd, target_os = "redox", target_os = "haiku"))] +// BSD, Haiku, Hurd, Redox, and Vita use `unsigned long`. +#[cfg(any( + bsd, + target_os = "redox", + target_os = "haiku", + target_os = "hurd", + target_os = "vita" +))] type _RawOpcode = c::c_ulong; // AIX, Emscripten, Fuchsia, Solaris, and WASI use a `int`. diff --git a/vendor/rustix/src/ioctl/patterns.rs b/vendor/rustix/src/ioctl/patterns.rs index 4b33d7d80..7bc5c4e86 100644 --- a/vendor/rustix/src/ioctl/patterns.rs +++ b/vendor/rustix/src/ioctl/patterns.rs @@ -6,6 +6,7 @@ use crate::backend::c; use crate::io::Result; use core::marker::PhantomData; +use core::ptr::addr_of_mut; use core::{fmt, mem}; /// Implements an `ioctl` with no real arguments. @@ -49,7 +50,7 @@ unsafe impl<Opcode: CompileTimeOpcode> Ioctl for NoArg<Opcode> { } } -/// Implements the traditional "getter" pattern for `ioctl`s. +/// Implements the traditional “getter” pattern for `ioctl`s. /// /// Some `ioctl`s just read data into the userspace. As this is a popular /// pattern this structure implements it. @@ -144,7 +145,7 @@ unsafe impl<Opcode: CompileTimeOpcode, Input> Ioctl for Setter<Opcode, Input> { const OPCODE: self::Opcode = Opcode::OPCODE; fn as_ptr(&mut self) -> *mut c::c_void { - &mut self.input as *mut Input as *mut c::c_void + addr_of_mut!(self.input).cast::<c::c_void>() } unsafe fn output_from_ptr(_: IoctlOutput, _: *mut c::c_void) -> Result<Self::Output> { @@ -166,6 +167,8 @@ impl<const OPCODE: RawOpcode> CompileTimeOpcode for BadOpcode<OPCODE> { } /// Provides a read code at compile time. +/// +/// This corresponds to the C macro `_IOR(GROUP, NUM, Data)`. #[cfg(any(linux_kernel, bsd))] pub struct ReadOpcode<const GROUP: u8, const NUM: u8, Data>(Data); @@ -175,6 +178,8 @@ impl<const GROUP: u8, const NUM: u8, Data> CompileTimeOpcode for ReadOpcode<GROU } /// Provides a write code at compile time. +/// +/// This corresponds to the C macro `_IOW(GROUP, NUM, Data)`. #[cfg(any(linux_kernel, bsd))] pub struct WriteOpcode<const GROUP: u8, const NUM: u8, Data>(Data); @@ -184,6 +189,8 @@ impl<const GROUP: u8, const NUM: u8, Data> CompileTimeOpcode for WriteOpcode<GRO } /// Provides a read/write code at compile time. +/// +/// This corresponds to the C macro `_IOWR(GROUP, NUM, Data)`. #[cfg(any(linux_kernel, bsd))] pub struct ReadWriteOpcode<const GROUP: u8, const NUM: u8, Data>(Data); @@ -193,6 +200,9 @@ impl<const GROUP: u8, const NUM: u8, Data> CompileTimeOpcode for ReadWriteOpcode } /// Provides a `None` code at compile time. +/// +/// This corresponds to the C macro `_IO(GROUP, NUM)` when `Data` is zero +/// sized. #[cfg(any(linux_kernel, bsd))] pub struct NoneOpcode<const GROUP: u8, const NUM: u8, Data>(Data); diff --git a/vendor/rustix/src/lib.rs b/vendor/rustix/src/lib.rs index a23006f9c..03f37d96e 100644 --- a/vendor/rustix/src/lib.rs +++ b/vendor/rustix/src/lib.rs @@ -94,7 +94,7 @@ //! [I/O-safe]: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md //! [`Result`]: https://doc.rust-lang.org/stable/std/result/enum.Result.html //! [`Arg`]: https://docs.rs/rustix/*/rustix/path/trait.Arg.html -//! [support for externally defined flags]: https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags +//! [support for externally defined flags]: https://docs.rs/bitflags/*/bitflags/#externally-defined-flags #![deny(missing_docs)] #![allow(stable_features)] @@ -115,13 +115,17 @@ )] #![cfg_attr(asm_experimental_arch, feature(asm_experimental_arch))] #![cfg_attr(not(feature = "all-apis"), allow(dead_code))] -// It is common in linux and libc APIs for types to vary between platforms. +// It is common in Linux and libc APIs for types to vary between platforms. #![allow(clippy::unnecessary_cast)] -// It is common in linux and libc APIs for types to vary between platforms. +// It is common in Linux and libc APIs for types to vary between platforms. #![allow(clippy::useless_conversion)] // Redox and WASI have enough differences that it isn't worth precisely -// conditionalizing all the `use`s for them. -#![cfg_attr(any(target_os = "redox", target_os = "wasi"), allow(unused_imports))] +// conditionalizing all the `use`s for them. Similar for if we don't have +// "all-apis". +#![cfg_attr( + any(target_os = "redox", target_os = "wasi", not(feature = "all-apis")), + allow(unused_imports) +)] #[cfg(all(feature = "alloc", not(feature = "rustc-dep-of-std")))] extern crate alloc; @@ -202,7 +206,7 @@ pub mod io; #[cfg_attr(doc_cfg, doc(cfg(feature = "io_uring")))] pub mod io_uring; pub mod ioctl; -#[cfg(not(any(windows, target_os = "espidf", target_os = "wasi")))] +#[cfg(not(any(windows, target_os = "espidf", target_os = "vita", target_os = "wasi")))] #[cfg(feature = "mm")] #[cfg_attr(doc_cfg, doc(cfg(feature = "mm")))] pub mod mm; @@ -246,6 +250,16 @@ pub mod pty; #[cfg(feature = "rand")] #[cfg_attr(doc_cfg, doc(cfg(feature = "rand")))] pub mod rand; +#[cfg(not(any( + windows, + target_os = "android", + target_os = "espidf", + target_os = "vita", + target_os = "wasi" +)))] +#[cfg(feature = "shm")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "shm")))] +pub mod shm; #[cfg(not(windows))] #[cfg(feature = "stdio")] #[cfg_attr(doc_cfg, doc(cfg(feature = "stdio")))] @@ -254,7 +268,7 @@ pub mod stdio; #[cfg(not(any(windows, target_os = "wasi")))] #[cfg_attr(doc_cfg, doc(cfg(feature = "system")))] pub mod system; -#[cfg(not(windows))] +#[cfg(not(any(windows, target_os = "vita")))] #[cfg(feature = "termios")] #[cfg_attr(doc_cfg, doc(cfg(feature = "termios")))] pub mod termios; @@ -326,7 +340,8 @@ mod clockid; feature = "runtime", feature = "termios", feature = "thread", - all(bsd, feature = "event") + all(bsd, feature = "event"), + all(linux_kernel, feature = "net") ))] mod pid; #[cfg(any(feature = "process", feature = "thread"))] @@ -369,6 +384,7 @@ mod timespec; feature = "time", target_arch = "x86", ) - ) + ), + all(linux_kernel, feature = "net") ))] mod ugid; diff --git a/vendor/rustix/src/maybe_polyfill/no_std/net/mod.rs b/vendor/rustix/src/maybe_polyfill/no_std/net/mod.rs index ff3356482..06e8f94d8 100644 --- a/vendor/rustix/src/maybe_polyfill/no_std/net/mod.rs +++ b/vendor/rustix/src/maybe_polyfill/no_std/net/mod.rs @@ -1,5 +1,6 @@ mod ip_addr; mod socket_addr; +#[allow(unused_imports)] pub use self::ip_addr::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope}; pub use self::socket_addr::{SocketAddr, SocketAddrV4, SocketAddrV6}; diff --git a/vendor/rustix/src/maybe_polyfill/no_std/os/fd/mod.rs b/vendor/rustix/src/maybe_polyfill/no_std/os/fd/mod.rs index 2d88fb076..ea5595345 100644 --- a/vendor/rustix/src/maybe_polyfill/no_std/os/fd/mod.rs +++ b/vendor/rustix/src/maybe_polyfill/no_std/os/fd/mod.rs @@ -5,8 +5,11 @@ //! All code in this file is licensed MIT or Apache 2.0 at your option. //! //! Owned and borrowed Unix-like file descriptors. +//! +//! This module is supported on Unix platforms and WASI, which both use a +//! similar file descriptor system for referencing OS resources. -#![cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] +#![cfg_attr(staged_api, stable(feature = "os_fd", since = "1.66.0"))] #![deny(unsafe_op_in_unsafe_fn)] // `RawFd`, `AsRawFd`, etc. @@ -15,5 +18,8 @@ mod raw; // `OwnedFd`, `AsFd`, etc. mod owned; +// Export the types and traits for the public API. +#[cfg_attr(staged_api, stable(feature = "os_fd", since = "1.66.0"))] pub use owned::*; +#[cfg_attr(staged_api, stable(feature = "os_fd", since = "1.66.0"))] pub use raw::*; diff --git a/vendor/rustix/src/maybe_polyfill/no_std/os/fd/owned.rs b/vendor/rustix/src/maybe_polyfill/no_std/os/fd/owned.rs index fffe34bff..ae9ffd673 100644 --- a/vendor/rustix/src/maybe_polyfill/no_std/os/fd/owned.rs +++ b/vendor/rustix/src/maybe_polyfill/no_std/os/fd/owned.rs @@ -1,6 +1,6 @@ //! The following is derived from Rust's //! library/std/src/os/fd/owned.rs at revision -//! fa68e73e9947be8ffc5b3b46d899e4953a44e7e9. +//! 334a54cd83191f38ad8046ed94c45de735c86c65. //! //! All code in this file is licensed MIT or Apache 2.0 at your option. //! @@ -18,8 +18,9 @@ use core::mem::forget; /// A borrowed file descriptor. /// -/// This has a lifetime parameter to tie it to the lifetime of something that -/// owns the file descriptor. +/// This has a lifetime parameter to tie it to the lifetime of something that owns the file +/// descriptor. For the duration of that lifetime, it is guaranteed that nobody will close the file +/// descriptor. /// /// This uses `repr(transparent)` and has the representation of a host file /// descriptor, so it can be used in FFI in places where a file descriptor is @@ -36,8 +37,8 @@ use core::mem::forget; // 32-bit c_int. Below is -2, in two's complement, but that only works out // because c_int is 32 bits. #[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE))] -#[cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] #[cfg_attr(rustc_attrs, rustc_nonnull_optimization_guaranteed)] +#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] pub struct BorrowedFd<'fd> { fd: RawFd, _phantom: PhantomData<&'fd OwnedFd>, @@ -45,7 +46,8 @@ pub struct BorrowedFd<'fd> { /// An owned file descriptor. /// -/// This closes the file descriptor on drop. +/// This closes the file descriptor on drop. It is guaranteed that nobody else will close the file +/// descriptor. /// /// This uses `repr(transparent)` and has the representation of a host file /// descriptor, so it can be used in FFI in places where a file descriptor is @@ -71,7 +73,11 @@ impl BorrowedFd<'_> { /// The resource pointed to by `fd` must remain open for the duration of /// the returned `BorrowedFd`, and it must not have the value `-1`. #[inline] - #[cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] + #[cfg_attr( + staged_api, + rustc_const_stable(feature = "io_safety", since = "1.63.0") + )] + #[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] pub const unsafe fn borrow_raw(fd: RawFd) -> Self { assert!(fd != u32::MAX as RawFd); // SAFETY: we just asserted that the value is in the valid range and isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned) @@ -184,7 +190,9 @@ impl FromRawFd for OwnedFd { /// # Safety /// /// The resource pointed to by `fd` must be open and suitable for assuming - /// ownership. The resource must not require any cleanup other than `close`. + /// [ownership][io-safety]. The resource must not require any cleanup other than `close`. + /// + /// [io-safety]: io#io-safety #[inline] unsafe fn from_raw_fd(fd: RawFd) -> Self { assert_ne!(fd, u32::MAX as RawFd); diff --git a/vendor/rustix/src/maybe_polyfill/no_std/os/fd/raw.rs b/vendor/rustix/src/maybe_polyfill/no_std/os/fd/raw.rs index 41968ab04..8f6b75ae1 100644 --- a/vendor/rustix/src/maybe_polyfill/no_std/os/fd/raw.rs +++ b/vendor/rustix/src/maybe_polyfill/no_std/os/fd/raw.rs @@ -1,6 +1,6 @@ //! The following is derived from Rust's //! library/std/src/os/fd/raw.rs at revision -//! fa68e73e9947be8ffc5b3b46d899e4953a44e7e9. +//! 334a54cd83191f38ad8046ed94c45de735c86c65. //! //! All code in this file is licensed MIT or Apache 2.0 at your option. //! @@ -71,7 +71,10 @@ pub trait FromRawFd { /// /// # Safety /// - /// The `fd` passed in must be a valid an open file descriptor. + /// The `fd` passed in must be an [owned file descriptor][io-safety]; + /// in particular, it must be open. + /// + /// [io-safety]: io#io-safety /// /// # Example /// diff --git a/vendor/rustix/src/mm/madvise.rs b/vendor/rustix/src/mm/madvise.rs index 868a31a5e..4015d1284 100644 --- a/vendor/rustix/src/mm/madvise.rs +++ b/vendor/rustix/src/mm/madvise.rs @@ -16,9 +16,9 @@ pub use backend::mm::types::Advice; /// /// # Safety /// -/// `addr` must be a valid pointer to memory that is appropriate to -/// call `posix_madvise` on. Some forms of `advice` may mutate the memory -/// or evoke a variety of side-effects on the mapping and/or the file. +/// `addr` must be a valid pointer to memory that is appropriate to call +/// `posix_madvise` on. Some forms of `advice` may mutate the memory or evoke a +/// variety of side-effects on the mapping and/or the file. /// /// # References /// - [POSIX] diff --git a/vendor/rustix/src/mm/mmap.rs b/vendor/rustix/src/mm/mmap.rs index 02badb9fd..22137a930 100644 --- a/vendor/rustix/src/mm/mmap.rs +++ b/vendor/rustix/src/mm/mmap.rs @@ -10,12 +10,40 @@ use crate::{backend, io}; use backend::fd::AsFd; use core::ffi::c_void; +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +pub use backend::mm::types::MlockAllFlags; #[cfg(linux_kernel)] pub use backend::mm::types::MlockFlags; #[cfg(any(target_os = "emscripten", target_os = "linux"))] pub use backend::mm::types::MremapFlags; pub use backend::mm::types::{MapFlags, MprotectFlags, ProtFlags}; +impl MapFlags { + /// Create `MAP_HUGETLB` with provided size of huge page. + /// + /// Under the hood it computes + /// `MAP_HUGETLB | (huge_page_size_log2 << MAP_HUGE_SHIFT)`. + /// `huge_page_size_log2` denotes logarithm of huge page size to use and + /// should be between 16 and 63 (inclusive). + /// + /// ``` + /// use rustix::mm::MapFlags; + /// + /// let f = MapFlags::hugetlb_with_size_log2(30).unwrap(); + /// assert_eq!(f, MapFlags::HUGETLB | MapFlags::HUGE_1GB); + /// ``` + #[cfg(linux_kernel)] + pub const fn hugetlb_with_size_log2(huge_page_size_log2: u32) -> Option<Self> { + use linux_raw_sys::general::{MAP_HUGETLB, MAP_HUGE_SHIFT}; + if 16 <= huge_page_size_log2 && huge_page_size_log2 <= 63 { + let bits = MAP_HUGETLB | (huge_page_size_log2 << MAP_HUGE_SHIFT); + Self::from_bits(bits) + } else { + None + } + } +} + /// `mmap(ptr, len, prot, flags, fd, offset)`—Create a file-backed memory /// mapping. /// @@ -314,3 +342,68 @@ pub unsafe fn mlock_with(ptr: *mut c_void, len: usize, flags: MlockFlags) -> io: pub unsafe fn munlock(ptr: *mut c_void, len: usize) -> io::Result<()> { backend::mm::syscalls::munlock(ptr, len) } + +/// Locks all pages mapped into the address space of the calling process. +/// +/// This includes the pages of the code, data, and stack segment, as well as +/// shared libraries, user space kernel data, shared memory, and memory-mapped +/// files. All mapped pages are guaranteed to be resident in RAM when the call +/// returns successfully; the pages are guaranteed to stay in RAM until later +/// unlocked. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// - [FreeBSD] +/// - [NetBSD] +/// - [OpenBSD] +/// - [DragonFly BSD] +/// - [illumos] +/// - [glibc] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/mlockall.html +/// [Linux]: https://man7.org/linux/man-pages/man2/mlockall.2.html +/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=mlockall&sektion=2 +/// [NetBSD]: https://man.netbsd.org/mlockall.2 +/// [OpenBSD]: https://man.openbsd.org/mlockall.2 +/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=mlockall§ion=2 +/// [illumos]: https://illumos.org/man/3C/mlockall +/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Page-Lock-Functions.html#index-mlockall +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +#[inline] +pub fn mlockall(flags: MlockAllFlags) -> io::Result<()> { + backend::mm::syscalls::mlockall(flags) +} + +/// Unlocks all pages mapped into the address space of the calling process. +/// +/// # Warnings +/// +/// This function is aware of all the memory pages in the process, as if it +/// were a debugger. It unlocks all the pages, which could potentially +/// compromise security assumptions made by code about memory it has +/// encapsulated. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// - [FreeBSD] +/// - [NetBSD] +/// - [OpenBSD] +/// - [DragonFly BSD] +/// - [illumos] +/// - [glibc] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/munlockall.html +/// [Linux]: https://man7.org/linux/man-pages/man2/munlockall.2.html +/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=munlockall&sektion=2 +/// [NetBSD]: https://man.netbsd.org/munlockall.2 +/// [OpenBSD]: https://man.openbsd.org/munlockall.2 +/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=munlockall§ion=2 +/// [illumos]: https://illumos.org/man/3C/munlockall +/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Page-Lock-Functions.html#index-munlockall +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +#[inline] +pub fn munlockall() -> io::Result<()> { + backend::mm::syscalls::munlockall() +} diff --git a/vendor/rustix/src/mm/msync.rs b/vendor/rustix/src/mm/msync.rs index 0306e36b9..c61d7c379 100644 --- a/vendor/rustix/src/mm/msync.rs +++ b/vendor/rustix/src/mm/msync.rs @@ -16,9 +16,9 @@ pub use backend::mm::types::MsyncFlags; /// /// # Safety /// -/// `addr` must be a valid pointer to memory that is appropriate to -/// call `msync` on. Some forms of `msync` may mutate the memory -/// or evoke a variety of side-effects on the mapping and/or the file. +/// `addr` must be a valid pointer to memory that is appropriate to call +/// `msync` on. Some forms of `msync` may mutate the memory or evoke a variety +/// of side-effects on the mapping and/or the file. /// /// # References /// - [POSIX] diff --git a/vendor/rustix/src/net/send_recv/mod.rs b/vendor/rustix/src/net/send_recv/mod.rs index 1dedd99cb..a377f65ad 100644 --- a/vendor/rustix/src/net/send_recv/mod.rs +++ b/vendor/rustix/src/net/send_recv/mod.rs @@ -8,10 +8,22 @@ use backend::fd::{AsFd, BorrowedFd}; pub use backend::net::send_recv::{RecvFlags, SendFlags}; -#[cfg(not(any(windows, target_os = "espidf", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any( + windows, + target_os = "espidf", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] mod msg; -#[cfg(not(any(windows, target_os = "espidf", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any( + windows, + target_os = "espidf", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] pub use msg::*; /// `recv(fd, buf, flags)`—Reads data from a socket. diff --git a/vendor/rustix/src/net/send_recv/msg.rs b/vendor/rustix/src/net/send_recv/msg.rs index 431aefa03..ea91cbfec 100644 --- a/vendor/rustix/src/net/send_recv/msg.rs +++ b/vendor/rustix/src/net/send_recv/msg.rs @@ -5,10 +5,14 @@ use crate::backend::{self, c}; use crate::fd::{AsFd, BorrowedFd, OwnedFd}; use crate::io::{self, IoSlice, IoSliceMut}; +#[cfg(linux_kernel)] +use crate::net::UCred; use core::iter::FusedIterator; use core::marker::PhantomData; -use core::mem::{size_of, size_of_val, take}; +use core::mem::{align_of, size_of, size_of_val, take}; +#[cfg(linux_kernel)] +use core::ptr::addr_of; use core::{ptr, slice}; use super::{RecvFlags, SendFlags, SocketAddrAny, SocketAddrV4, SocketAddrV6}; @@ -22,6 +26,11 @@ macro_rules! cmsg_space { $len * ::core::mem::size_of::<$crate::fd::BorrowedFd<'static>>(), ) }; + (ScmCredentials($len:expr)) => { + $crate::net::__cmsg_space( + $len * ::core::mem::size_of::<$crate::net::UCred>(), + ) + }; // Combo Rules (($($($x:tt)*),+)) => { @@ -33,8 +42,19 @@ macro_rules! cmsg_space { } #[doc(hidden)] -pub fn __cmsg_space(len: usize) -> usize { - unsafe { c::CMSG_SPACE(len.try_into().expect("CMSG_SPACE size overflow")) as usize } +pub const fn __cmsg_space(len: usize) -> usize { + // Add `align_of::<c::cmsghdr>()` so that we can align the user-provided + // `&[u8]` to the required alignment boundary. + let len = len + align_of::<c::cmsghdr>(); + + // Convert `len` to `u32` for `CMSG_SPACE`. This would be `try_into()` if + // we could call that in a `const fn`. + let converted_len = len as u32; + if converted_len as usize != len { + unreachable!(); // `CMSG_SPACE` size overflow + } + + unsafe { c::CMSG_SPACE(converted_len) as usize } } /// Ancillary message for [`sendmsg`], [`sendmsg_v4`], [`sendmsg_v6`], @@ -42,24 +62,23 @@ pub fn __cmsg_space(len: usize) -> usize { #[non_exhaustive] pub enum SendAncillaryMessage<'slice, 'fd> { /// Send file descriptors. + #[doc(alias = "SCM_RIGHTS")] ScmRights(&'slice [BorrowedFd<'fd>]), + /// Send process credentials. + #[cfg(linux_kernel)] + #[doc(alias = "SCM_CREDENTIAL")] + ScmCredentials(UCred), } impl SendAncillaryMessage<'_, '_> { /// Get the maximum size of an ancillary message. /// /// This can be helpful in determining the size of the buffer you allocate. - pub fn size(&self) -> usize { - let total_bytes = match self { - Self::ScmRights(slice) => size_of_val(*slice), - }; - - unsafe { - c::CMSG_SPACE( - total_bytes - .try_into() - .expect("size too large for CMSG_SPACE"), - ) as usize + pub const fn size(&self) -> usize { + match self { + Self::ScmRights(slice) => cmsg_space!(ScmRights(slice.len())), + #[cfg(linux_kernel)] + Self::ScmCredentials(_) => cmsg_space!(ScmCredentials(1)), } } } @@ -68,10 +87,16 @@ impl SendAncillaryMessage<'_, '_> { #[non_exhaustive] pub enum RecvAncillaryMessage<'a> { /// Received file descriptors. + #[doc(alias = "SCM_RIGHTS")] ScmRights(AncillaryIter<'a, OwnedFd>), + /// Received process credentials. + #[cfg(linux_kernel)] + #[doc(alias = "SCM_CREDENTIALS")] + ScmCredentials(UCred), } -/// Buffer for sending ancillary messages. +/// Buffer for sending ancillary messages with [`sendmsg`], [`sendmsg_v4`], +/// [`sendmsg_v6`], [`sendmsg_unix`], and [`sendmsg_any`]. pub struct SendAncillaryBuffer<'buf, 'slice, 'fd> { /// Raw byte buffer for messages. buffer: &'buf mut [u8], @@ -91,15 +116,20 @@ impl<'buf> From<&'buf mut [u8]> for SendAncillaryBuffer<'buf, '_, '_> { impl Default for SendAncillaryBuffer<'_, '_, '_> { fn default() -> Self { - Self::new(&mut []) + Self { + buffer: &mut [], + length: 0, + _phantom: PhantomData, + } } } impl<'buf, 'slice, 'fd> SendAncillaryBuffer<'buf, 'slice, 'fd> { /// Create a new, empty `SendAncillaryBuffer` from a raw byte buffer. + #[inline] pub fn new(buffer: &'buf mut [u8]) -> Self { Self { - buffer, + buffer: align_for_cmsghdr(buffer), length: 0, _phantom: PhantomData, } @@ -138,6 +168,13 @@ impl<'buf, 'slice, 'fd> SendAncillaryBuffer<'buf, 'slice, 'fd> { unsafe { slice::from_raw_parts(fds.as_ptr().cast::<u8>(), size_of_val(fds)) }; self.push_ancillary(fds_bytes, c::SOL_SOCKET as _, c::SCM_RIGHTS as _) } + #[cfg(linux_kernel)] + SendAncillaryMessage::ScmCredentials(ucred) => { + let ucred_bytes = unsafe { + slice::from_raw_parts(addr_of!(ucred).cast::<u8>(), size_of_val(&ucred)) + }; + self.push_ancillary(ucred_bytes, c::SOL_SOCKET as _, c::SCM_CREDENTIALS as _) + } } } @@ -191,7 +228,8 @@ impl<'slice, 'fd> Extend<SendAncillaryMessage<'slice, 'fd>> } } -/// Buffer for receiving ancillary messages. +/// Buffer for receiving ancillary messages with [`recvmsg`]. +#[derive(Default)] pub struct RecvAncillaryBuffer<'buf> { /// Raw byte buffer for messages. buffer: &'buf mut [u8], @@ -209,17 +247,12 @@ impl<'buf> From<&'buf mut [u8]> for RecvAncillaryBuffer<'buf> { } } -impl Default for RecvAncillaryBuffer<'_> { - fn default() -> Self { - Self::new(&mut []) - } -} - impl<'buf> RecvAncillaryBuffer<'buf> { /// Create a new, empty `RecvAncillaryBuffer` from a raw byte buffer. + #[inline] pub fn new(buffer: &'buf mut [u8]) -> Self { Self { - buffer, + buffer: align_for_cmsghdr(buffer), read: 0, length: 0, } @@ -274,7 +307,17 @@ impl Drop for RecvAncillaryBuffer<'_> { } } -/// An iterator that drains messages from a `RecvAncillaryBuffer`. +/// Return a slice of `buffer` starting at the first `cmsghdr` alignment +/// boundary. +#[inline] +fn align_for_cmsghdr(buffer: &mut [u8]) -> &mut [u8] { + let align = align_of::<c::cmsghdr>(); + let addr = buffer.as_ptr() as usize; + let adjusted = (addr + (align - 1)) & align.wrapping_neg(); + &mut buffer[adjusted - addr..] +} + +/// An iterator that drains messages from a [`RecvAncillaryBuffer`]. pub struct AncillaryDrain<'buf> { /// Inner iterator over messages. messages: messages::Messages<'buf>, @@ -287,14 +330,14 @@ pub struct AncillaryDrain<'buf> { } impl<'buf> AncillaryDrain<'buf> { - /// A closure that converts a message into a `RecvAncillaryMessage`. + /// A closure that converts a message into a [`RecvAncillaryMessage`]. fn cvt_msg( read: &mut usize, length: &mut usize, msg: &c::cmsghdr, ) -> Option<RecvAncillaryMessage<'buf>> { unsafe { - // Advance the "read" pointer. + // Advance the `read` pointer. let msg_len = msg.cmsg_len as usize; *read += msg_len; *length -= msg_len; @@ -315,6 +358,15 @@ impl<'buf> AncillaryDrain<'buf> { Some(RecvAncillaryMessage::ScmRights(fds)) } + #[cfg(linux_kernel)] + (c::SOL_SOCKET, c::SCM_CREDENTIALS) => { + if payload_len >= size_of::<UCred>() { + let ucred = payload.as_ptr().cast::<UCred>().read_unaligned(); + Some(RecvAncillaryMessage::ScmCredentials(ucred)) + } else { + None + } + } _ => None, } } @@ -693,7 +745,7 @@ mod messages { /// An iterator over the messages in an ancillary buffer. pub(super) struct Messages<'buf> { - /// The message header we're using to iterator over the messages. + /// The message header we're using to iterate over the messages. msghdr: c::msghdr, /// The current pointer to the next message header to return. diff --git a/vendor/rustix/src/net/socket.rs b/vendor/rustix/src/net/socket.rs index 8727ca53b..fe7439562 100644 --- a/vendor/rustix/src/net/socket.rs +++ b/vendor/rustix/src/net/socket.rs @@ -453,6 +453,44 @@ pub fn connect_unix<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrUnix) -> io::Result<( backend::net::syscalls::connect_unix(sockfd.as_fd(), addr) } +/// `connect(sockfd, {.sa_family = AF_UNSPEC}, sizeof(struct sockaddr))` +/// — Dissolve the socket's association. +/// +/// On UDP sockets, BSD platforms report [`Errno::AFNOSUPPORT`] or +/// [`Errno::INVAL`] even if the disconnect was successful. +/// +/// # References +/// - [Beej's Guide to Network Programming] +/// - [POSIX] +/// - [Linux] +/// - [Apple] +/// - [Winsock2] +/// - [FreeBSD] +/// - [NetBSD] +/// - [OpenBSD] +/// - [DragonFly BSD] +/// - [illumos] +/// - [glibc] +/// +/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html +/// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html +/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html +/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect +/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2 +/// [NetBSD]: https://man.netbsd.org/connect.2 +/// [OpenBSD]: https://man.openbsd.org/connect.2 +/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect§ion=2 +/// [illumos]: https://illumos.org/man/3SOCKET/connect +/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Connecting.html +/// [`Errno::AFNOSUPPORT`]: io::Errno::AFNOSUPPORT +/// [`Errno::INVAL`]: io::Errno::INVAL +#[inline] +#[doc(alias = "connect")] +pub fn connect_unspec<Fd: AsFd>(sockfd: Fd) -> io::Result<()> { + backend::net::syscalls::connect_unspec(sockfd.as_fd()) +} + /// `listen(fd, backlog)`—Enables listening for incoming connections. /// /// # References diff --git a/vendor/rustix/src/net/socket_addr_any.rs b/vendor/rustix/src/net/socket_addr_any.rs index 7cb124e4c..a649015f4 100644 --- a/vendor/rustix/src/net/socket_addr_any.rs +++ b/vendor/rustix/src/net/socket_addr_any.rs @@ -11,7 +11,7 @@ #[cfg(unix)] use crate::net::SocketAddrUnix; -use crate::net::{AddressFamily, SocketAddrV4, SocketAddrV6}; +use crate::net::{AddressFamily, SocketAddr, SocketAddrV4, SocketAddrV6}; use crate::{backend, io}; #[cfg(feature = "std")] use core::fmt; @@ -32,6 +32,16 @@ pub enum SocketAddrAny { Unix(SocketAddrUnix), } +impl From<SocketAddr> for SocketAddrAny { + #[inline] + fn from(from: SocketAddr) -> Self { + match from { + SocketAddr::V4(v4) => Self::V4(v4), + SocketAddr::V6(v6) => Self::V6(v6), + } + } +} + impl From<SocketAddrV4> for SocketAddrAny { #[inline] fn from(from: SocketAddrV4) -> Self { diff --git a/vendor/rustix/src/net/sockopt.rs b/vendor/rustix/src/net/sockopt.rs index 1939155d9..afeaf0b33 100644 --- a/vendor/rustix/src/net/sockopt.rs +++ b/vendor/rustix/src/net/sockopt.rs @@ -1,7 +1,144 @@ //! `getsockopt` and `setsockopt` functions. //! -//! In the rustix API, there is a separate function for each option, so that -//! it can be given an option-specific type signature. +//! In the rustix API, there is a separate function for each option, so that it +//! can be given an option-specific type signature. +//! +//! # References for all `get_*` functions: +//! +//! - [POSIX `getsockopt`] +//! - [Linux `getsockopt`] +//! - [Winsock2 `getsockopt`] +//! - [Apple `getsockopt`] +//! - [FreeBSD `getsockopt`] +//! - [NetBSD `getsockopt`] +//! - [OpenBSD `getsockopt`] +//! - [DragonFly BSD `getsockopt`] +//! - [illumos `getsockopt`] +//! - [glibc `getsockopt`] +//! +//! [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html +//! [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html +//! [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt +//! [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html +//! [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 +//! [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 +//! [OpenBSD `getsockopt`]: https://man.openbsd.org/getsockopt.2 +//! [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 +//! [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt +//! [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html +//! +//! # References for all `set_*` functions: +//! +//! - [POSIX `setsockopt`] +//! - [Linux `setsockopt`] +//! - [Winsock2 `setsockopt`] +//! - [Apple `setsockopt`] +//! - [FreeBSD `setsockopt`] +//! - [NetBSD `setsockopt`] +//! - [OpenBSD `setsockopt`] +//! - [DragonFly BSD `setsockopt`] +//! - [illumos `setsockopt`] +//! - [glibc `setsockopt`] +//! +//! [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html +//! [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html +//! [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt +//! [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html +//! [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 +//! [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 +//! [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 +//! [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 +//! [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt +//! [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html +//! +//! # References for `get_socket_*` and `set_socket_*` functions: +//! +//! - [References for all `get_*` functions] +//! - [References for all `set_*` functions] +//! - [POSIX `sys/socket.h`] +//! - [Linux `socket`] +//! - [Winsock2 `SOL_SOCKET` options] +//! - [glibc `SOL_SOCKET` Options] +//! +//! [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html +//! [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html +//! [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options +//! [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +//! +//! # References for `get_ip_*` and `set_ip_*` functions: +//! +//! - [References for all `get_*` functions] +//! - [References for all `set_*` functions] +//! - [POSIX `netinet/in.h`] +//! - [Linux `ip`] +//! - [Winsock2 `IPPROTO_IP` options] +//! - [Apple `ip`] +//! - [FreeBSD `ip`] +//! - [NetBSD `ip`] +//! - [OpenBSD `ip`] +//! - [DragonFly BSD `ip`] +//! - [illumos `ip`] +//! +//! [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html +//! [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html +//! [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options +//! [Apple `ip`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip.4.auto.html +//! [FreeBSD `ip`]: https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 +//! [NetBSD `ip`]: https://man.netbsd.org/ip.4 +//! [OpenBSD `ip`]: https://man.openbsd.org/ip.4 +//! [DragonFly BSD `ip`]: https://man.dragonflybsd.org/?command=ip§ion=4 +//! [illumos `ip`]: https://illumos.org/man/4P/ip +//! +//! # References for `get_ipv6_*` and `set_ipv6_*` functions: +//! +//! - [References for all `get_*` functions] +//! - [References for all `set_*` functions] +//! - [POSIX `netinet/in.h`] +//! - [Linux `ipv6`] +//! - [Winsock2 `IPPROTO_IPV6` options] +//! - [Apple `ip6`] +//! - [FreeBSD `ip6`] +//! - [NetBSD `ip6`] +//! - [OpenBSD `ip6`] +//! - [DragonFly BSD `ip6`] +//! - [illumos `ip6`] +//! +//! [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html +//! [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html +//! [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options +//! [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html +//! [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 +//! [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 +//! [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 +//! [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 +//! [illumos `ip6`]: https://illumos.org/man/4P/ip6 +//! +//! # References for `get_tcp_*` and `set_tcp_*` functions: +//! +//! - [References for all `get_*` functions] +//! - [References for all `set_*` functions] +//! - [POSIX `netinet/tcp.h`] +//! - [Linux `tcp`] +//! - [Winsock2 `IPPROTO_TCP` options] +//! - [Apple `tcp`] +//! - [FreeBSD `tcp`] +//! - [NetBSD `tcp`] +//! - [OpenBSD `tcp`] +//! - [DragonFly BSD `tcp`] +//! - [illumos `tcp`] +//! +//! [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html +//! [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html +//! [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options +//! [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html +//! [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 +//! [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 +//! [OpenBSD `tcp`]: https://man.openbsd.org/tcp.4 +//! [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 +//! [illumos `tcp`]: https://illumos.org/man/4P/tcp +//! +//! [References for all `get_*` functions]: #references-for-all-get_-functions +//! [References for all `set_*` functions]: #references-for-all-set_-functions #![doc(alias = "getsockopt")] #![doc(alias = "setsockopt")] @@ -16,19 +153,38 @@ target_os = "haiku", target_os = "netbsd", target_os = "nto", + target_os = "vita", )))] use crate::net::AddressFamily; +#[cfg(any( + linux_kernel, + target_os = "freebsd", + target_os = "fuchsia", + target_os = "openbsd", + target_os = "redox", + target_env = "newlib" +))] +use crate::net::Protocol; +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +use crate::net::SocketAddrV4; +#[cfg(linux_kernel)] +use crate::net::SocketAddrV6; use crate::net::{Ipv4Addr, Ipv6Addr, SocketType}; use crate::{backend, io}; +#[cfg(feature = "alloc")] +#[cfg(any( + linux_like, + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos" +))] +use alloc::string::String; use backend::c; use backend::fd::AsFd; use core::time::Duration; /// Timeout identifier for use with [`set_socket_timeout`] and /// [`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(u32)] pub enum Timeout { @@ -41,759 +197,241 @@ pub enum Timeout { /// `getsockopt(fd, SOL_SOCKET, SO_TYPE)`—Returns the type of a socket. /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_TYPE")] pub fn get_socket_type<Fd: AsFd>(fd: Fd) -> io::Result<SocketType> { - backend::net::syscalls::sockopt::get_socket_type(fd.as_fd()) + backend::net::sockopt::get_socket_type(fd.as_fd()) } -/// `setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, value)` +/// `setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, value)`—Set whether local +/// addresses may be reused in `bind`. /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `setsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `setsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/setsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/setsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/setsockopt -/// [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_REUSEADDR")] pub fn set_socket_reuseaddr<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_reuseaddr(fd.as_fd(), value) + backend::net::sockopt::set_socket_reuseaddr(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_REUSEADDR)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_REUSEADDR")] pub fn get_socket_reuseaddr<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::syscalls::sockopt::get_socket_reuseaddr(fd.as_fd()) + backend::net::sockopt::get_socket_reuseaddr(fd.as_fd()) } -/// `setsockopt(fd, SOL_SOCKET, SO_BROADCAST, broadcast)` +/// `setsockopt(fd, SOL_SOCKET, SO_BROADCAST, value)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `setsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `setsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/setsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/setsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/setsockopt -/// [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_BROADCAST")] -pub fn set_socket_broadcast<Fd: AsFd>(fd: Fd, broadcast: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_broadcast(fd.as_fd(), broadcast) +pub fn set_socket_broadcast<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_socket_broadcast(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_BROADCAST)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_BROADCAST")] pub fn get_socket_broadcast<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::syscalls::sockopt::get_socket_broadcast(fd.as_fd()) + backend::net::sockopt::get_socket_broadcast(fd.as_fd()) } -/// `setsockopt(fd, SOL_SOCKET, SO_LINGER, linger)` +/// `setsockopt(fd, SOL_SOCKET, SO_LINGER, value)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `setsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `setsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/setsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/setsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/setsockopt -/// [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_LINGER")] -pub fn set_socket_linger<Fd: AsFd>(fd: Fd, linger: Option<Duration>) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_linger(fd.as_fd(), linger) +pub fn set_socket_linger<Fd: AsFd>(fd: Fd, value: Option<Duration>) -> io::Result<()> { + backend::net::sockopt::set_socket_linger(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_LINGER)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_LINGER")] pub fn get_socket_linger<Fd: AsFd>(fd: Fd) -> io::Result<Option<Duration>> { - backend::net::syscalls::sockopt::get_socket_linger(fd.as_fd()) + backend::net::sockopt::get_socket_linger(fd.as_fd()) } -/// `setsockopt(fd, SOL_SOCKET, SO_PASSCRED, passcred)` +/// `setsockopt(fd, SOL_SOCKET, SO_PASSCRED, value)` /// -/// # References -/// - [Linux `setsockopt`] -/// - [Linux `socket`] +/// See the [module-level documentation] for more. /// -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[cfg(linux_kernel)] #[inline] #[doc(alias = "SO_PASSCRED")] -pub fn set_socket_passcred<Fd: AsFd>(fd: Fd, passcred: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_passcred(fd.as_fd(), passcred) +pub fn set_socket_passcred<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_socket_passcred(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_PASSCRED)` /// -/// # References -/// - [Linux `getsockopt`] -/// - [Linux `socket`] +/// See the [module-level documentation] for more. /// -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[cfg(linux_kernel)] #[inline] #[doc(alias = "SO_PASSCRED")] pub fn get_socket_passcred<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::syscalls::sockopt::get_socket_passcred(fd.as_fd()) + backend::net::sockopt::get_socket_passcred(fd.as_fd()) } -/// `setsockopt(fd, SOL_SOCKET, id, timeout)`—Set the sending or receiving +/// `setsockopt(fd, SOL_SOCKET, id, value)`—Set the sending or receiving /// timeout. /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `setsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `setsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/setsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/setsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/setsockopt -/// [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_RCVTIMEO")] #[doc(alias = "SO_SNDTIMEO")] pub fn set_socket_timeout<Fd: AsFd>( fd: Fd, id: Timeout, - timeout: Option<Duration>, + value: Option<Duration>, ) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_timeout(fd.as_fd(), id, timeout) + backend::net::sockopt::set_socket_timeout(fd.as_fd(), id, value) } /// `getsockopt(fd, SOL_SOCKET, id)`—Get the sending or receiving timeout. /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_RCVTIMEO")] #[doc(alias = "SO_SNDTIMEO")] pub fn get_socket_timeout<Fd: AsFd>(fd: Fd, id: Timeout) -> io::Result<Option<Duration>> { - backend::net::syscalls::sockopt::get_socket_timeout(fd.as_fd(), id) + backend::net::sockopt::get_socket_timeout(fd.as_fd(), id) } /// `getsockopt(fd, SOL_SOCKET, SO_ERROR)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_ERROR")] pub fn get_socket_error<Fd: AsFd>(fd: Fd) -> io::Result<Result<(), io::Errno>> { - backend::net::syscalls::sockopt::get_socket_error(fd.as_fd()) + backend::net::sockopt::get_socket_error(fd.as_fd()) } /// `getsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html -#[cfg(any(apple, target_os = "freebsd"))] +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions +#[cfg(any(apple, freebsdlike, target_os = "netbsd"))] #[doc(alias = "SO_NOSIGPIPE")] #[inline] pub fn get_socket_nosigpipe<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::syscalls::sockopt::get_socket_nosigpipe(fd.as_fd()) + backend::net::sockopt::get_socket_nosigpipe(fd.as_fd()) } -/// `setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, val)` +/// `setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, value)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `setsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `setsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/setsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/setsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/setsockopt -/// [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html -#[cfg(any(apple, target_os = "freebsd"))] +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions +#[cfg(any(apple, freebsdlike, target_os = "netbsd"))] #[doc(alias = "SO_NOSIGPIPE")] #[inline] -pub fn set_socket_nosigpipe<Fd: AsFd>(fd: Fd, val: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_nosigpipe(fd.as_fd(), val) +pub fn set_socket_nosigpipe<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_socket_nosigpipe(fd.as_fd(), value) } -/// `setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, keepalive)` +/// `setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, value)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `setsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `setsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/setsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/setsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/setsockopt -/// [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_KEEPALIVE")] -pub fn set_socket_keepalive<Fd: AsFd>(fd: Fd, keepalive: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_keepalive(fd.as_fd(), keepalive) +pub fn set_socket_keepalive<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_socket_keepalive(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_KEEPALIVE")] pub fn get_socket_keepalive<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::syscalls::sockopt::get_socket_keepalive(fd.as_fd()) + backend::net::sockopt::get_socket_keepalive(fd.as_fd()) } -/// `setsockopt(fd, SOL_SOCKET, SO_RCVBUF, size)` +/// `setsockopt(fd, SOL_SOCKET, SO_RCVBUF, value)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `setsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `setsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/setsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/setsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/setsockopt -/// [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_RCVBUF")] -pub fn set_socket_recv_buffer_size<Fd: AsFd>(fd: Fd, size: usize) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_recv_buffer_size(fd.as_fd(), size) +pub fn set_socket_recv_buffer_size<Fd: AsFd>(fd: Fd, value: usize) -> io::Result<()> { + backend::net::sockopt::set_socket_recv_buffer_size(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_RCVBUF)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_RCVBUF")] pub fn get_socket_recv_buffer_size<Fd: AsFd>(fd: Fd) -> io::Result<usize> { - backend::net::syscalls::sockopt::get_socket_recv_buffer_size(fd.as_fd()) + backend::net::sockopt::get_socket_recv_buffer_size(fd.as_fd()) } -/// `setsockopt(fd, SOL_SOCKET, SO_SNDBUF, size)` +/// `setsockopt(fd, SOL_SOCKET, SO_SNDBUF, value)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `setsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `setsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/setsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/setsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/setsockopt -/// [glibc `setsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_SNDBUF")] -pub fn set_socket_send_buffer_size<Fd: AsFd>(fd: Fd, size: usize) -> io::Result<()> { - backend::net::syscalls::sockopt::set_socket_send_buffer_size(fd.as_fd(), size) +pub fn set_socket_send_buffer_size<Fd: AsFd>(fd: Fd, value: usize) -> io::Result<()> { + backend::net::sockopt::set_socket_send_buffer_size(fd.as_fd(), value) } /// `getsockopt(fd, SOL_SOCKET, SO_SNDBUF)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "SO_SNDBUF")] pub fn get_socket_send_buffer_size<Fd: AsFd>(fd: Fd) -> io::Result<usize> { - backend::net::syscalls::sockopt::get_socket_send_buffer_size(fd.as_fd()) + backend::net::sockopt::get_socket_send_buffer_size(fd.as_fd()) } /// `getsockopt(fd, SOL_SOCKET, SO_DOMAIN)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[cfg(not(any( apple, windows, @@ -804,709 +442,314 @@ pub fn get_socket_send_buffer_size<Fd: AsFd>(fd: Fd) -> io::Result<usize> { target_os = "haiku", target_os = "netbsd", target_os = "nto", + target_os = "vita", )))] #[inline] #[doc(alias = "SO_DOMAIN")] pub fn get_socket_domain<Fd: AsFd>(fd: Fd) -> io::Result<AddressFamily> { - backend::net::syscalls::sockopt::get_socket_domain(fd.as_fd()) + backend::net::sockopt::get_socket_domain(fd.as_fd()) } /// `getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `sys/socket.h`] -/// - [Linux `getsockopt`] -/// - [Linux `socket`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `SOL_SOCKET` options] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc `getsockopt`] -/// - [glibc `SOL_SOCKET` Options] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockopt.2 -/// [OpenBSD]: https://man.openbsd.org/getsockopt.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt -/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html -/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[cfg(not(apple))] // Apple platforms declare the constant, but do not actually implement it. #[inline] #[doc(alias = "SO_ACCEPTCONN")] pub fn get_socket_acceptconn<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::syscalls::sockopt::get_socket_acceptconn(fd.as_fd()) + backend::net::sockopt::get_socket_acceptconn(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_IP, IP_TTL, ttl)` +/// `setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, value)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ip`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IP` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip`] -/// - [illumos `setsockopt`] -/// - [illumos `ip`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip`]: https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip`]: https://man.netbsd.org/ip.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip`]: https://man.openbsd.org/ip.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip`]: https://man.dragonflybsd.org/?command=ip§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip`]: https://illumos.org/man/4P/ip +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions +#[inline] +#[doc(alias = "SO_OOBINLINE")] +pub fn set_socket_oobinline<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_socket_oobinline(fd.as_fd(), value) +} + +/// `getsockopt(fd, SOL_SOCKET, SO_OOBINLINE)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions +#[inline] +#[doc(alias = "SO_OOBINLINE")] +pub fn get_socket_oobinline<Fd: AsFd>(fd: Fd) -> io::Result<bool> { + backend::net::sockopt::get_socket_oobinline(fd.as_fd()) +} + +/// `setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions +#[cfg(not(any(solarish, windows)))] +#[cfg(not(windows))] +#[inline] +#[doc(alias = "SO_REUSEPORT")] +pub fn set_socket_reuseport<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_socket_reuseport(fd.as_fd(), value) +} + +/// `getsockopt(fd, SOL_SOCKET, SO_REUSEPORT)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions +#[cfg(not(any(solarish, windows)))] +#[inline] +#[doc(alias = "SO_REUSEPORT")] +pub fn get_socket_reuseport<Fd: AsFd>(fd: Fd) -> io::Result<bool> { + backend::net::sockopt::get_socket_reuseport(fd.as_fd()) +} + +/// `setsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions +#[cfg(target_os = "freebsd")] +#[inline] +#[doc(alias = "SO_REUSEPORT_LB")] +pub fn set_socket_reuseport_lb<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_socket_reuseport_lb(fd.as_fd(), value) +} + +/// `getsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions +#[cfg(target_os = "freebsd")] +#[inline] +#[doc(alias = "SO_REUSEPORT_LB")] +pub fn get_socket_reuseport_lb<Fd: AsFd>(fd: Fd) -> io::Result<bool> { + backend::net::sockopt::get_socket_reuseport_lb(fd.as_fd()) +} + +/// `getsockopt(fd, SOL_SOCKET, SO_PROTOCOL)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions +#[cfg(any( + linux_kernel, + target_os = "freebsd", + target_os = "fuchsia", + target_os = "openbsd", + target_os = "redox", + target_env = "newlib" +))] +#[inline] +#[doc(alias = "SO_PROTOCOL")] +pub fn get_socket_protocol<Fd: AsFd>(fd: Fd) -> io::Result<Option<Protocol>> { + backend::net::sockopt::get_socket_protocol(fd.as_fd()) +} + +/// `getsockopt(fd, SOL_SOCKET, SO_COOKIE)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions +#[cfg(target_os = "linux")] +#[inline] +#[doc(alias = "SO_COOKIE")] +pub fn get_socket_cookie<Fd: AsFd>(fd: Fd) -> io::Result<u64> { + backend::net::sockopt::get_socket_cookie(fd.as_fd()) +} + +/// `getsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions +#[cfg(target_os = "linux")] +#[inline] +#[doc(alias = "SO_INCOMING_CPU")] +pub fn get_socket_incoming_cpu<Fd: AsFd>(fd: Fd) -> io::Result<u32> { + backend::net::sockopt::get_socket_incoming_cpu(fd.as_fd()) +} + +/// `setsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions +#[cfg(target_os = "linux")] +#[inline] +#[doc(alias = "SO_INCOMING_CPU")] +pub fn set_socket_incoming_cpu<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { + backend::net::sockopt::set_socket_incoming_cpu(fd.as_fd(), value) +} + +/// `setsockopt(fd, IPPROTO_IP, IP_TTL, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions #[inline] #[doc(alias = "IP_TTL")] -pub fn set_ip_ttl<Fd: AsFd>(fd: Fd, ttl: u32) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ip_ttl(fd.as_fd(), ttl) +pub fn set_ip_ttl<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { + backend::net::sockopt::set_ip_ttl(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IP, IP_TTL)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `getsockopt`] -/// - [Linux `ip`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_IP` options] -/// - [Apple `getsockopt`] -/// - [Apple `ip`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `ip`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `ip`] -/// - [OpenBSD `getsockopt`] -/// - [OpenBSD `ip`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `ip`] -/// - [illumos `getsockopt`] -/// - [illumos `ip`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip`]: https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip`]: https://man.netbsd.org/ip.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip`]: https://man.openbsd.org/ip.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip`]: https://man.dragonflybsd.org/?command=ip§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip`]: https://illumos.org/man/4P/ip +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions #[inline] #[doc(alias = "IP_TTL")] pub fn get_ip_ttl<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::syscalls::sockopt::get_ip_ttl(fd.as_fd()) + backend::net::sockopt::get_ip_ttl(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, only_v6)` +/// `setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, value)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `setsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IPV6_V6ONLY")] -pub fn set_ipv6_v6only<Fd: AsFd>(fd: Fd, only_v6: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ipv6_v6only(fd.as_fd(), only_v6) +pub fn set_ipv6_v6only<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_ipv6_v6only(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `getsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `getsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `getsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `getsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `getsockopt`]: https://man.openbsd.org/getsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IPV6_V6ONLY")] pub fn get_ipv6_v6only<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::syscalls::sockopt::get_ipv6_v6only(fd.as_fd()) + backend::net::sockopt::get_ipv6_v6only(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, multicast_loop)` +/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, value)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ip`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IP` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip`] -/// - [illumos `setsockopt`] -/// - [illumos `ip`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip`]: https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip`]: https://man.netbsd.org/ip.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip`]: https://man.openbsd.org/ip.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip`]: https://man.dragonflybsd.org/?command=ip§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip`]: https://illumos.org/man/4P/ip +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions #[inline] #[doc(alias = "IP_MULTICAST_LOOP")] -pub fn set_ip_multicast_loop<Fd: AsFd>(fd: Fd, multicast_loop: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ip_multicast_loop(fd.as_fd(), multicast_loop) +pub fn set_ip_multicast_loop<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_ip_multicast_loop(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `getsockopt`] -/// - [Linux `ip`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_IP` options] -/// - [Apple `getsockopt`] -/// - [Apple `ip`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `ip`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `ip`] -/// - [OpenBSD `getsockopt`] -/// - [OpenBSD `ip`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `ip`] -/// - [illumos `getsockopt`] -/// - [illumos `ip`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions #[inline] #[doc(alias = "IP_MULTICAST_LOOP")] pub fn get_ip_multicast_loop<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::syscalls::sockopt::get_ip_multicast_loop(fd.as_fd()) + backend::net::sockopt::get_ip_multicast_loop(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, multicast_ttl)` +/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, value)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ip`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IP` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip`] -/// - [illumos `setsockopt`] -/// - [illumos `ip`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip`]: https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip`]: https://man.netbsd.org/ip.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip`]: https://man.openbsd.org/ip.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip`]: https://man.dragonflybsd.org/?command=ip§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip`]: https://illumos.org/man/4P/ip +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions #[inline] #[doc(alias = "IP_MULTICAST_TTL")] -pub fn set_ip_multicast_ttl<Fd: AsFd>(fd: Fd, multicast_ttl: u32) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ip_multicast_ttl(fd.as_fd(), multicast_ttl) +pub fn set_ip_multicast_ttl<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { + backend::net::sockopt::set_ip_multicast_ttl(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `getsockopt`] -/// - [Linux `ip`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_IP` options] -/// - [Apple `getsockopt`] -/// - [Apple `ip`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `ip`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `ip`] -/// - [OpenBSD `getsockopt`] -/// - [OpenBSD `ip`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `ip`] -/// - [illumos `getsockopt`] -/// - [illumos `ip`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions #[inline] #[doc(alias = "IP_MULTICAST_TTL")] pub fn get_ip_multicast_ttl<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::syscalls::sockopt::get_ip_multicast_ttl(fd.as_fd()) + backend::net::sockopt::get_ip_multicast_ttl(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, multicast_loop)` +/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, value)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `setsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IPV6_MULTICAST_LOOP")] -pub fn set_ipv6_multicast_loop<Fd: AsFd>(fd: Fd, multicast_loop: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ipv6_multicast_loop(fd.as_fd(), multicast_loop) +pub fn set_ipv6_multicast_loop<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_ipv6_multicast_loop(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `getsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `getsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `getsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `getsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `getsockopt`]: https://man.openbsd.org/getsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IPV6_MULTICAST_LOOP")] pub fn get_ipv6_multicast_loop<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::syscalls::sockopt::get_ipv6_multicast_loop(fd.as_fd()) + backend::net::sockopt::get_ipv6_multicast_loop(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, multicast_hops)` +/// `getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `setsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] -#[doc(alias = "IP_MULTICAST_TTL")] -pub fn set_ipv6_multicast_hops<Fd: AsFd>(fd: Fd, multicast_hops: u32) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ipv6_multicast_hops(fd.as_fd(), multicast_hops) +#[doc(alias = "IPV6_UNICAST_HOPS")] +pub fn get_ipv6_unicast_hops<Fd: AsFd>(fd: Fd) -> io::Result<u8> { + backend::net::sockopt::get_ipv6_unicast_hops(fd.as_fd()) } -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS)` +/// `setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, value)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `getsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `getsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `getsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `getsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `getsockopt`]: https://man.openbsd.org/getsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IPV6_UNICAST_HOPS")] -pub fn get_ipv6_unicast_hops<Fd: AsFd>(fd: Fd) -> io::Result<u8> { - backend::net::syscalls::sockopt::get_ipv6_unicast_hops(fd.as_fd()) +pub fn set_ipv6_unicast_hops<Fd: AsFd>(fd: Fd, value: Option<u8>) -> io::Result<()> { + backend::net::sockopt::set_ipv6_unicast_hops(fd.as_fd(), value) } -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, unicast_hops)` +/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, value)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `setsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] -#[doc(alias = "IPV6_UNICAST_HOPS")] -pub fn set_ipv6_unicast_hops<Fd: AsFd>(fd: Fd, unicast_hops: Option<u8>) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ipv6_unicast_hops(fd.as_fd(), unicast_hops) +#[doc(alias = "IPV6_MULTICAST_HOPS")] +pub fn set_ipv6_multicast_hops<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { + backend::net::sockopt::set_ipv6_multicast_hops(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `getsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `getsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `getsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `getsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `getsockopt`]: https://man.openbsd.org/getsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] -#[doc(alias = "IP_MULTICAST_TTL")] +#[doc(alias = "IPV6_MULTICAST_HOPS")] pub fn get_ipv6_multicast_hops<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::syscalls::sockopt::get_ipv6_multicast_hops(fd.as_fd()) + backend::net::sockopt::get_ipv6_multicast_hops(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, multiaddr, interface)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ip`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IP` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip`] -/// - [illumos `setsockopt`] -/// - [illumos `ip`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip`]: https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip`]: https://man.netbsd.org/ip.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip`]: https://man.openbsd.org/ip.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip`]: https://man.dragonflybsd.org/?command=ip§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip`]: https://illumos.org/man/4P/ip +/// This is similar to [`set_ip_add_membership`] but always sets `ifindex` +/// value to zero. +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions #[inline] #[doc(alias = "IP_ADD_MEMBERSHIP")] pub fn set_ip_add_membership<Fd: AsFd>( @@ -1514,51 +757,90 @@ pub fn set_ip_add_membership<Fd: AsFd>( multiaddr: &Ipv4Addr, interface: &Ipv4Addr, ) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ip_add_membership(fd.as_fd(), multiaddr, interface) + backend::net::sockopt::set_ip_add_membership(fd.as_fd(), multiaddr, interface) +} + +/// `setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, multiaddr, address, +/// ifindex)` +/// +/// This is similar to [`set_ip_add_membership_with_ifindex`] but additionally +/// allows a `ifindex` value to be given. +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[cfg(any( + apple, + freebsdlike, + linux_like, + target_os = "fuchsia", + target_os = "openbsd" +))] +#[inline] +#[doc(alias = "IP_ADD_MEMBERSHIP")] +pub fn set_ip_add_membership_with_ifindex<Fd: AsFd>( + fd: Fd, + multiaddr: &Ipv4Addr, + address: &Ipv4Addr, + ifindex: i32, +) -> io::Result<()> { + backend::net::sockopt::set_ip_add_membership_with_ifindex( + fd.as_fd(), + multiaddr, + address, + ifindex, + ) +} + +/// `setsockopt(fd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] +#[inline] +#[doc(alias = "IP_ADD_SOURCE_MEMBERSHIP")] +pub fn set_ip_add_source_membership<Fd: AsFd>( + fd: Fd, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> io::Result<()> { + backend::net::sockopt::set_ip_add_source_membership( + fd.as_fd(), + multiaddr, + interface, + sourceaddr, + ) +} + +/// `setsockopt(fd, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] +#[inline] +#[doc(alias = "IP_DROP_SOURCE_MEMBERSHIP")] +pub fn set_ip_drop_source_membership<Fd: AsFd>( + fd: Fd, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> io::Result<()> { + backend::net::sockopt::set_ip_drop_source_membership( + fd.as_fd(), + multiaddr, + interface, + sourceaddr, + ) } /// `setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, multiaddr, interface)` /// -/// `IPV6_ADD_MEMBERSHIP` is the same as `IPV6_JOIN_GROUP` in POSIX. +/// See the [module-level documentation] for more. /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `setsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IPV6_JOIN_GROUP")] #[doc(alias = "IPV6_ADD_MEMBERSHIP")] @@ -1567,49 +849,17 @@ pub fn set_ipv6_add_membership<Fd: AsFd>( multiaddr: &Ipv6Addr, interface: u32, ) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ipv6_add_membership(fd.as_fd(), multiaddr, interface) + backend::net::sockopt::set_ipv6_add_membership(fd.as_fd(), multiaddr, interface) } /// `setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, multiaddr, interface)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ip`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IP` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip`] -/// - [illumos `setsockopt`] -/// - [illumos `ip`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip`]: https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip`]: https://man.netbsd.org/ip.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip`]: https://man.openbsd.org/ip.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip`]: https://man.dragonflybsd.org/?command=ip§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip`]: https://illumos.org/man/4P/ip +/// This is similar to [`set_ip_drop_membership`] but always sets `ifindex` +/// value to zero. +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions #[inline] #[doc(alias = "IP_DROP_MEMBERSHIP")] pub fn set_ip_drop_membership<Fd: AsFd>( @@ -1617,51 +867,45 @@ pub fn set_ip_drop_membership<Fd: AsFd>( multiaddr: &Ipv4Addr, interface: &Ipv4Addr, ) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ip_drop_membership(fd.as_fd(), multiaddr, interface) + backend::net::sockopt::set_ip_drop_membership(fd.as_fd(), multiaddr, interface) +} + +/// `setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, multiaddr, interface)` +/// +/// This is similar to [`set_ip_drop_membership_with_ifindex`] but additionally +/// allows a `ifindex` value to be given. +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[cfg(any( + apple, + freebsdlike, + linux_like, + target_os = "fuchsia", + target_os = "openbsd" +))] +#[inline] +#[doc(alias = "IP_DROP_MEMBERSHIP")] +pub fn set_ip_drop_membership_with_ifindex<Fd: AsFd>( + fd: Fd, + multiaddr: &Ipv4Addr, + address: &Ipv4Addr, + ifindex: i32, +) -> io::Result<()> { + backend::net::sockopt::set_ip_drop_membership_with_ifindex( + fd.as_fd(), + multiaddr, + address, + ifindex, + ) } /// `setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, multiaddr, interface)` /// -/// `IPV6_DROP_MEMBERSHIP` is the same as `IPV6_LEAVE_GROUP` in POSIX. +/// See the [module-level documentation] for more. /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/in.h`] -/// - [Linux `setsockopt`] -/// - [Linux `ipv6`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_IPV6` options] -/// - [Apple `setsockopt`] -/// - [Apple `ip6`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `ip6`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `ip6`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `ip6`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `ip6`] -/// - [illumos `setsockopt`] -/// - [illumos `ip6`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `ip6`]: https://illumos.org/man/4P/ip6 +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions #[inline] #[doc(alias = "IPV6_LEAVE_GROUP")] #[doc(alias = "IPV6_DROP_MEMBERSHIP")] @@ -1670,361 +914,462 @@ pub fn set_ipv6_drop_membership<Fd: AsFd>( multiaddr: &Ipv6Addr, interface: u32, ) -> io::Result<()> { - backend::net::syscalls::sockopt::set_ipv6_drop_membership(fd.as_fd(), multiaddr, interface) + backend::net::sockopt::set_ipv6_drop_membership(fd.as_fd(), multiaddr, interface) } -/// `setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, nodelay)` +/// `setsockopt(fd, IPPROTO_IP, IP_TOS, value)` /// -/// # References -/// - [POSIX `setsockopt`] -/// - [POSIX `netinet/tcp.h`] -/// - [Linux `setsockopt`] -/// - [Linux `tcp`] -/// - [Winsock2 `setsockopt`] -/// - [Winsock2 `IPPROTO_TCP` options] -/// - [Apple `setsockopt`] -/// - [Apple `tcp`] -/// - [FreeBSD `setsockopt`] -/// - [FreeBSD `tcp`] -/// - [NetBSD `setsockopt`] -/// - [NetBSD `tcp`] -/// - [OpenBSD `setsockopt`] -/// - [OpenBSD `tcp`] -/// - [DragonFly BSD `setsockopt`] -/// - [DragonFly BSD `tcp`] -/// - [illumos `setsockopt`] -/// - [illumos `tcp`] -/// -/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html -/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html -/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -/// [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -/// [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html -/// [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -/// [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -/// [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -/// [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -/// [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -/// [OpenBSD `tcp`]: https://man.openbsd.org/tcp.4 -/// [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -/// [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -/// [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -/// [illumos `tcp`]: https://illumos.org/man/4P/tcp +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "haiku", + target_os = "nto", + target_env = "newlib" +))] +#[inline] +#[doc(alias = "IP_TOS")] +pub fn set_ip_tos<Fd: AsFd>(fd: Fd, value: u8) -> io::Result<()> { + backend::net::sockopt::set_ip_tos(fd.as_fd(), value) +} + +/// `getsockopt(fd, IPPROTO_IP, IP_TOS)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "haiku", + target_os = "nto", + target_env = "newlib" +))] +#[inline] +#[doc(alias = "IP_TOS")] +pub fn get_ip_tos<Fd: AsFd>(fd: Fd) -> io::Result<u8> { + backend::net::sockopt::get_ip_tos(fd.as_fd()) +} + +/// `setsockopt(fd, IPPROTO_IP, IP_RECVTOS, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[cfg(any(apple, linux_like, target_os = "freebsd", target_os = "fuchsia"))] +#[inline] +#[doc(alias = "IP_RECVTOS")] +pub fn set_ip_recvtos<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_ip_recvtos(fd.as_fd(), value) +} + +/// `getsockopt(fd, IPPROTO_IP, IP_RECVTOS)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions +#[cfg(any(apple, linux_like, target_os = "freebsd", target_os = "fuchsia"))] +#[inline] +#[doc(alias = "IP_RECVTOS")] +pub fn get_ip_recvtos<Fd: AsFd>(fd: Fd) -> io::Result<bool> { + backend::net::sockopt::get_ip_recvtos(fd.as_fd()) +} + +/// `setsockopt(fd, IPPROTO_IPV6, IPV6_RECVTCLASS, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions +#[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "nto" +))] +#[inline] +#[doc(alias = "IPV6_RECVTCLASS")] +pub fn set_ipv6_recvtclass<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_ipv6_recvtclass(fd.as_fd(), value) +} + +/// `getsockopt(fd, IPPROTO_IPV6, IPV6_RECVTCLASS)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions +#[cfg(any( + bsd, + linux_like, + target_os = "aix", + target_os = "fuchsia", + target_os = "nto" +))] +#[inline] +#[doc(alias = "IPV6_RECVTCLASS")] +pub fn get_ipv6_recvtclass<Fd: AsFd>(fd: Fd) -> io::Result<bool> { + backend::net::sockopt::get_ipv6_recvtclass(fd.as_fd()) +} + +/// `setsockopt(fd, IPPROTO_IP, IP_FREEBIND, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[inline] +#[doc(alias = "IP_FREEBIND")] +pub fn set_ip_freebind<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_ip_freebind(fd.as_fd(), value) +} + +/// `getsockopt(fd, IPPROTO_IP, IP_FREEBIND)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[inline] +#[doc(alias = "IP_FREEBIND")] +pub fn get_ip_freebind<Fd: AsFd>(fd: Fd) -> io::Result<bool> { + backend::net::sockopt::get_ip_freebind(fd.as_fd()) +} + +/// `setsockopt(fd, IPPROTO_IPV6, IPV6_FREEBIND, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions +#[cfg(linux_kernel)] +#[inline] +#[doc(alias = "IPV6_FREEBIND")] +pub fn set_ipv6_freebind<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_ipv6_freebind(fd.as_fd(), value) +} + +/// `getsockopt(fd, IPPROTO_IPV6, IPV6_FREEBIND)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions +#[cfg(linux_kernel)] +#[inline] +#[doc(alias = "IPV6_FREEBIND")] +pub fn get_ipv6_freebind<Fd: AsFd>(fd: Fd) -> io::Result<bool> { + backend::net::sockopt::get_ipv6_freebind(fd.as_fd()) +} + +/// `getsockopt(fd, IPPROTO_IP, SO_ORIGINAL_DST)` +/// +/// Even though this corresponnds to a `SO_*` constant, it is an `IPPROTO_IP` +/// option. +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[inline] +#[doc(alias = "SO_ORIGINAL_DST")] +pub fn get_ip_original_dst<Fd: AsFd>(fd: Fd) -> io::Result<SocketAddrV4> { + backend::net::sockopt::get_ip_original_dst(fd.as_fd()) +} + +/// `getsockopt(fd, IPPROTO_IPV6, IP6T_SO_ORIGINAL_DST)` +/// +/// Even though this corresponnds to a `IP6T_*` constant, it is an +/// `IPPROTO_IPV6` option. +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions +#[cfg(linux_kernel)] +#[inline] +#[doc(alias = "IP6T_SO_ORIGINAL_DST")] +pub fn get_ipv6_original_dst<Fd: AsFd>(fd: Fd) -> io::Result<SocketAddrV6> { + backend::net::sockopt::get_ipv6_original_dst(fd.as_fd()) +} + +/// `setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions +#[cfg(not(any( + solarish, + windows, + target_os = "espidf", + target_os = "haiku", + target_os = "vita" +)))] +#[inline] +#[doc(alias = "IPV6_TCLASS")] +pub fn set_ipv6_tclass<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { + backend::net::sockopt::set_ipv6_tclass(fd.as_fd(), value) +} + +/// `getsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions +#[cfg(not(any( + solarish, + windows, + target_os = "espidf", + target_os = "haiku", + target_os = "vita" +)))] +#[inline] +#[doc(alias = "IPV6_TCLASS")] +pub fn get_ipv6_tclass<Fd: AsFd>(fd: Fd) -> io::Result<u32> { + backend::net::sockopt::get_ipv6_tclass(fd.as_fd()) +} + +/// `setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions #[inline] #[doc(alias = "TCP_NODELAY")] -pub fn set_tcp_nodelay<Fd: AsFd>(fd: Fd, nodelay: bool) -> io::Result<()> { - backend::net::syscalls::sockopt::set_tcp_nodelay(fd.as_fd(), nodelay) +pub fn set_tcp_nodelay<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_tcp_nodelay(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_TCP, TCP_NODELAY)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/tcp.h`] -/// - [Linux `getsockopt`] -/// - [Linux `tcp`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_TCP` options] -/// - [Apple `getsockopt`] -/// - [Apple `tcp`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `tcp`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `tcp`] -/// - [OpenBSD `getsockopt`] -/// - [OpenBSD `tcp`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `tcp`] -/// - [illumos `getsockopt`] -/// - [illumos `tcp`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -/// [OpenBSD `getsockopt`]: https://man.openbsd.org/getsockopt.2 -/// [OpenBSD `tcp`]: https://man.openbsd.org/tcp.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `tcp`]: https://illumos.org/man/4P/tcp +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions #[inline] #[doc(alias = "TCP_NODELAY")] pub fn get_tcp_nodelay<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::syscalls::sockopt::get_tcp_nodelay(fd.as_fd()) + backend::net::sockopt::get_tcp_nodelay(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, count)` +/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, value)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/tcp.h`] -/// - [Linux `getsockopt`] -/// - [Linux `tcp`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_TCP` options] -/// - [Apple `getsockopt`] -/// - [Apple `tcp`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `tcp`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `tcp`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `tcp`] -/// - [illumos `getsockopt`] -/// - [illumos `tcp`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `tcp`]: https://illumos.org/man/4P/tcp -#[inline] +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +#[inline] #[doc(alias = "TCP_KEEPCNT")] -pub fn set_tcp_keepcnt<Fd: AsFd>(fd: Fd, count: u32) -> io::Result<()> { - backend::net::syscalls::sockopt::set_tcp_keepcnt(fd.as_fd(), count) +pub fn set_tcp_keepcnt<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { + backend::net::sockopt::set_tcp_keepcnt(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/tcp.h`] -/// - [Linux `getsockopt`] -/// - [Linux `tcp`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_TCP` options] -/// - [Apple `getsockopt`] -/// - [Apple `tcp`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `tcp`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `tcp`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `tcp`] -/// - [illumos `getsockopt`] -/// - [illumos `tcp`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `tcp`]: https://illumos.org/man/4P/tcp -#[inline] +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +#[inline] #[doc(alias = "TCP_KEEPCNT")] pub fn get_tcp_keepcnt<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::syscalls::sockopt::get_tcp_keepcnt(fd.as_fd()) + backend::net::sockopt::get_tcp_keepcnt(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, duration)` +/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, value)` /// /// `TCP_KEEPALIVE` on Apple platforms. /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/tcp.h`] -/// - [Linux `getsockopt`] -/// - [Linux `tcp`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_TCP` options] -/// - [Apple `getsockopt`] -/// - [Apple `tcp`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `tcp`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `tcp`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `tcp`] -/// - [illumos `getsockopt`] -/// - [illumos `tcp`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `tcp`]: https://illumos.org/man/4P/tcp -#[inline] +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +#[inline] #[doc(alias = "TCP_KEEPIDLE")] -pub fn set_tcp_keepidle<Fd: AsFd>(fd: Fd, duration: Duration) -> io::Result<()> { - backend::net::syscalls::sockopt::set_tcp_keepidle(fd.as_fd(), duration) +pub fn set_tcp_keepidle<Fd: AsFd>(fd: Fd, value: Duration) -> io::Result<()> { + backend::net::sockopt::set_tcp_keepidle(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE)` /// /// `TCP_KEEPALIVE` on Apple platforms. /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/tcp.h`] -/// - [Linux `getsockopt`] -/// - [Linux `tcp`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_TCP` options] -/// - [Apple `getsockopt`] -/// - [Apple `tcp`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `tcp`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `tcp`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `tcp`] -/// - [illumos `getsockopt`] -/// - [illumos `tcp`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `tcp`]: https://illumos.org/man/4P/tcp -#[inline] +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +#[inline] #[doc(alias = "TCP_KEEPIDLE")] pub fn get_tcp_keepidle<Fd: AsFd>(fd: Fd) -> io::Result<Duration> { - backend::net::syscalls::sockopt::get_tcp_keepidle(fd.as_fd()) + backend::net::sockopt::get_tcp_keepidle(fd.as_fd()) } -/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, duration)` +/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, value)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/tcp.h`] -/// - [Linux `getsockopt`] -/// - [Linux `tcp`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_TCP` options] -/// - [Apple `getsockopt`] -/// - [Apple `tcp`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `tcp`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `tcp`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `tcp`] -/// - [illumos `getsockopt`] -/// - [illumos `tcp`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `tcp`]: https://illumos.org/man/4P/tcp -#[inline] +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +#[inline] #[doc(alias = "TCP_KEEPINTVL")] -pub fn set_tcp_keepintvl<Fd: AsFd>(fd: Fd, duration: Duration) -> io::Result<()> { - backend::net::syscalls::sockopt::set_tcp_keepintvl(fd.as_fd(), duration) +pub fn set_tcp_keepintvl<Fd: AsFd>(fd: Fd, value: Duration) -> io::Result<()> { + backend::net::sockopt::set_tcp_keepintvl(fd.as_fd(), value) } /// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL)` /// -/// # References -/// - [POSIX `getsockopt`] -/// - [POSIX `netinet/tcp.h`] -/// - [Linux `getsockopt`] -/// - [Linux `tcp`] -/// - [Winsock2 `getsockopt`] -/// - [Winsock2 `IPPROTO_TCP` options] -/// - [Apple `getsockopt`] -/// - [Apple `tcp`] -/// - [FreeBSD `getsockopt`] -/// - [FreeBSD `tcp`] -/// - [NetBSD `getsockopt`] -/// - [NetBSD `tcp`] -/// - [DragonFly BSD `getsockopt`] -/// - [DragonFly BSD `tcp`] -/// - [illumos `getsockopt`] -/// - [illumos `tcp`] -/// -/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html -/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html -/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -/// [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -/// [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html -/// [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -/// [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -/// [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -/// [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -/// [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -/// [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -/// [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -/// [illumos `tcp`]: https://illumos.org/man/4P/tcp -#[inline] +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions #[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))] +#[inline] #[doc(alias = "TCP_KEEPINTVL")] pub fn get_tcp_keepintvl<Fd: AsFd>(fd: Fd) -> io::Result<Duration> { - backend::net::syscalls::sockopt::get_tcp_keepintvl(fd.as_fd()) + backend::net::sockopt::get_tcp_keepintvl(fd.as_fd()) +} + +/// `setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions +#[cfg(any(linux_like, target_os = "fuchsia"))] +#[inline] +#[doc(alias = "TCP_USER_TIMEOUT")] +pub fn set_tcp_user_timeout<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { + backend::net::sockopt::set_tcp_user_timeout(fd.as_fd(), value) +} + +/// `getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions +#[cfg(any(linux_like, target_os = "fuchsia"))] +#[inline] +#[doc(alias = "TCP_USER_TIMEOUT")] +pub fn get_tcp_user_timeout<Fd: AsFd>(fd: Fd) -> io::Result<u32> { + backend::net::sockopt::get_tcp_user_timeout(fd.as_fd()) +} + +/// `setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions +#[cfg(any(linux_like, target_os = "fuchsia"))] +#[inline] +#[doc(alias = "TCP_QUICKACK")] +pub fn set_tcp_quickack<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_tcp_quickack(fd.as_fd(), value) +} + +/// `getsockopt(fd, IPPROTO_TCP, TCP_QUICKACK)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions +#[cfg(any(linux_like, target_os = "fuchsia"))] +#[inline] +#[doc(alias = "TCP_QUICKACK")] +pub fn get_tcp_quickack<Fd: AsFd>(fd: Fd) -> io::Result<bool> { + backend::net::sockopt::get_tcp_quickack(fd.as_fd()) +} + +/// `setsockopt(fd, IPPROTO_TCP, TCP_CONGESTION, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions +#[cfg(any( + linux_like, + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos" +))] +#[inline] +#[doc(alias = "TCP_CONGESTION")] +pub fn set_tcp_congestion<Fd: AsFd>(fd: Fd, value: &str) -> io::Result<()> { + backend::net::sockopt::set_tcp_congestion(fd.as_fd(), value) +} + +/// `getsockopt(fd, IPPROTO_TCP, TCP_CONGESTION)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions +#[cfg(feature = "alloc")] +#[cfg(any( + linux_like, + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos" +))] +#[inline] +#[doc(alias = "TCP_CONGESTION")] +pub fn get_tcp_congestion<Fd: AsFd>(fd: Fd) -> io::Result<String> { + backend::net::sockopt::get_tcp_congestion(fd.as_fd()) +} + +/// `setsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions +#[cfg(any(linux_like, target_os = "fuchsia"))] +#[inline] +#[doc(alias = "TCP_THIN_LINEAR_TIMEOUTS")] +pub fn set_tcp_thin_linear_timeouts<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_tcp_thin_linear_timeouts(fd.as_fd(), value) +} + +/// `getsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions +#[cfg(any(linux_like, target_os = "fuchsia"))] +#[inline] +#[doc(alias = "TCP_THIN_LINEAR_TIMEOUTS")] +pub fn get_tcp_thin_linear_timeouts<Fd: AsFd>(fd: Fd) -> io::Result<bool> { + backend::net::sockopt::get_tcp_thin_linear_timeouts(fd.as_fd()) +} + +/// `setsockopt(fd, IPPROTO_TCP, TCP_CORK, value)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions +#[cfg(any(linux_like, solarish, target_os = "fuchsia"))] +#[inline] +#[doc(alias = "TCP_CORK")] +pub fn set_tcp_cork<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { + backend::net::sockopt::set_tcp_cork(fd.as_fd(), value) +} + +/// `getsockopt(fd, IPPROTO_TCP, TCP_CORK)` +/// +/// See the [module-level documentation] for more. +/// +/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions +#[cfg(any(linux_like, solarish, target_os = "fuchsia"))] +#[inline] +#[doc(alias = "TCP_CORK")] +pub fn get_tcp_cork<Fd: AsFd>(fd: Fd) -> io::Result<bool> { + backend::net::sockopt::get_tcp_cork(fd.as_fd()) +} + +/// Get credentials of Unix domain socket peer process +/// +/// # References +/// - [Linux `unix`] +/// +/// [Linux `unix`]: https://man7.org/linux/man-pages/man7/unix.7.html +#[cfg(linux_kernel)] +#[doc(alias = "SO_PEERCRED")] +pub fn get_socket_peercred<Fd: AsFd>(fd: Fd) -> io::Result<super::UCred> { + backend::net::sockopt::get_socket_peercred(fd.as_fd()) } #[test] diff --git a/vendor/rustix/src/net/types.rs b/vendor/rustix/src/net/types.rs index 53116f9c8..711174354 100644 --- a/vendor/rustix/src/net/types.rs +++ b/vendor/rustix/src/net/types.rs @@ -92,6 +92,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const NETLINK: Self = Self(c::AF_NETLINK as _); /// `AF_UNIX`, aka `AF_LOCAL` @@ -106,16 +107,18 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const AX25: Self = Self(c::AF_AX25 as _); /// `AF_IPX` #[cfg(not(any( - target_os = "espidf", target_os = "aix", + target_os = "espidf", + target_os = "vita", )))] pub const IPX: Self = Self(c::AF_IPX as _); /// `AF_APPLETALK` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] pub const APPLETALK: Self = Self(c::AF_APPLETALK as _); /// `AF_NETROM` #[cfg(not(any( @@ -126,6 +129,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const NETROM: Self = Self(c::AF_NETROM as _); /// `AF_BRIDGE` @@ -137,6 +141,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const BRIDGE: Self = Self(c::AF_BRIDGE as _); /// `AF_ATMPVC` @@ -148,6 +153,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const ATMPVC: Self = Self(c::AF_ATMPVC as _); /// `AF_X25` @@ -158,6 +164,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const X25: Self = Self(c::AF_X25 as _); /// `AF_ROSE` @@ -169,10 +176,11 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const ROSE: Self = Self(c::AF_ROSE as _); /// `AF_DECnet` - #[cfg(not(any(target_os = "espidf", target_os = "haiku")))] + #[cfg(not(any(target_os = "espidf", target_os = "haiku", target_os = "vita")))] pub const DECnet: Self = Self(c::AF_DECnet as _); /// `AF_NETBEUI` #[cfg(not(any( @@ -183,6 +191,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const NETBEUI: Self = Self(c::AF_NETBEUI as _); /// `AF_SECURITY` @@ -194,6 +203,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const SECURITY: Self = Self(c::AF_SECURITY as _); /// `AF_KEY` @@ -204,6 +214,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const KEY: Self = Self(c::AF_KEY as _); /// `AF_PACKET` @@ -219,6 +230,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const PACKET: Self = Self(c::AF_PACKET as _); /// `AF_ASH` @@ -230,6 +242,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const ASH: Self = Self(c::AF_ASH as _); /// `AF_ECONET` @@ -241,6 +254,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const ECONET: Self = Self(c::AF_ECONET as _); /// `AF_ATMSVC` @@ -252,6 +266,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const ATMSVC: Self = Self(c::AF_ATMSVC as _); /// `AF_RDS` @@ -263,10 +278,11 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const RDS: Self = Self(c::AF_RDS as _); /// `AF_SNA` - #[cfg(not(any(target_os = "espidf", target_os = "haiku")))] + #[cfg(not(any(target_os = "espidf", target_os = "haiku", target_os = "vita")))] pub const SNA: Self = Self(c::AF_SNA as _); /// `AF_IRDA` #[cfg(not(any( @@ -276,6 +292,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const IRDA: Self = Self(c::AF_IRDA as _); /// `AF_PPPOX` @@ -287,6 +304,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const PPPOX: Self = Self(c::AF_PPPOX as _); /// `AF_WANPIPE` @@ -298,6 +316,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const WANPIPE: Self = Self(c::AF_WANPIPE as _); /// `AF_LLC` @@ -309,6 +328,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const LLC: Self = Self(c::AF_LLC as _); /// `AF_CAN` @@ -320,6 +340,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const CAN: Self = Self(c::AF_CAN as _); /// `AF_TIPC` @@ -331,6 +352,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const TIPC: Self = Self(c::AF_TIPC as _); /// `AF_BLUETOOTH` @@ -340,6 +362,7 @@ impl AddressFamily { windows, target_os = "aix", target_os = "espidf", + target_os = "vita", )))] pub const BLUETOOTH: Self = Self(c::AF_BLUETOOTH as _); /// `AF_IUCV` @@ -351,6 +374,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const IUCV: Self = Self(c::AF_IUCV as _); /// `AF_RXRPC` @@ -362,6 +386,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const RXRPC: Self = Self(c::AF_RXRPC as _); /// `AF_ISDN` @@ -371,6 +396,7 @@ impl AddressFamily { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "vita", )))] pub const ISDN: Self = Self(c::AF_ISDN as _); /// `AF_PHONET` @@ -382,6 +408,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const PHONET: Self = Self(c::AF_PHONET as _); /// `AF_IEEE802154` @@ -393,6 +420,7 @@ impl AddressFamily { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const IEEE802154: Self = Self(c::AF_IEEE802154 as _); /// `AF_802` @@ -610,26 +638,58 @@ pub mod ipproto { /// `IPPROTO_ICMP` pub const ICMP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ICMP as _)); /// `IPPROTO_IGMP` - #[cfg(not(any(solarish, target_os = "espidf", target_os = "haiku")))] + #[cfg(not(any( + solarish, + target_os = "espidf", + target_os = "haiku", + target_os = "vita" + )))] pub const IGMP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_IGMP as _)); /// `IPPROTO_IPIP` - #[cfg(not(any(solarish, windows, target_os = "espidf", target_os = "haiku")))] + #[cfg(not(any( + solarish, + windows, + target_os = "espidf", + target_os = "haiku", + target_os = "vita" + )))] pub const IPIP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_IPIP as _)); /// `IPPROTO_TCP` pub const TCP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_TCP as _)); /// `IPPROTO_EGP` - #[cfg(not(any(solarish, target_os = "espidf", target_os = "haiku")))] + #[cfg(not(any( + solarish, + target_os = "espidf", + target_os = "haiku", + target_os = "vita" + )))] pub const EGP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_EGP as _)); /// `IPPROTO_PUP` - #[cfg(not(any(solarish, target_os = "espidf", target_os = "haiku")))] + #[cfg(not(any( + solarish, + target_os = "espidf", + target_os = "haiku", + target_os = "vita" + )))] pub const PUP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_PUP as _)); /// `IPPROTO_UDP` pub const UDP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_UDP as _)); /// `IPPROTO_IDP` - #[cfg(not(any(solarish, target_os = "espidf", target_os = "haiku")))] + #[cfg(not(any( + solarish, + target_os = "espidf", + target_os = "haiku", + target_os = "vita" + )))] pub const IDP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_IDP as _)); /// `IPPROTO_TP` - #[cfg(not(any(solarish, windows, target_os = "espidf", target_os = "haiku")))] + #[cfg(not(any( + solarish, + windows, + target_os = "espidf", + target_os = "haiku", + target_os = "vita" + )))] pub const TP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_TP as _)); /// `IPPROTO_DCCP` #[cfg(not(any( @@ -642,21 +702,44 @@ pub mod ipproto { target_os = "haiku", target_os = "nto", target_os = "openbsd", + target_os = "vita", )))] pub const DCCP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_DCCP as _)); /// `IPPROTO_IPV6` pub const IPV6: Protocol = Protocol(new_raw_protocol(c::IPPROTO_IPV6 as _)); /// `IPPROTO_RSVP` - #[cfg(not(any(solarish, windows, target_os = "espidf", target_os = "haiku")))] + #[cfg(not(any( + solarish, + windows, + target_os = "espidf", + target_os = "haiku", + target_os = "vita" + )))] pub const RSVP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_RSVP as _)); /// `IPPROTO_GRE` - #[cfg(not(any(solarish, windows, target_os = "espidf", target_os = "haiku")))] + #[cfg(not(any( + solarish, + windows, + target_os = "espidf", + target_os = "haiku", + target_os = "vita" + )))] pub const GRE: Protocol = Protocol(new_raw_protocol(c::IPPROTO_GRE as _)); /// `IPPROTO_ESP` - #[cfg(not(any(solarish, target_os = "espidf", target_os = "haiku")))] + #[cfg(not(any( + solarish, + target_os = "espidf", + target_os = "haiku", + target_os = "vita" + )))] pub const ESP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ESP as _)); /// `IPPROTO_AH` - #[cfg(not(any(solarish, target_os = "espidf", target_os = "haiku")))] + #[cfg(not(any( + solarish, + target_os = "espidf", + target_os = "haiku", + target_os = "vita" + )))] pub const AH: Protocol = Protocol(new_raw_protocol(c::IPPROTO_AH as _)); /// `IPPROTO_MTP` #[cfg(not(any( @@ -667,6 +750,7 @@ pub mod ipproto { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const MTP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_MTP as _)); /// `IPPROTO_BEETPH` @@ -677,7 +761,8 @@ pub mod ipproto { target_os = "aix", target_os = "espidf", target_os = "haiku", - target_os = "nto" + target_os = "nto", + target_os = "vita", )))] pub const BEETPH: Protocol = Protocol(new_raw_protocol(c::IPPROTO_BEETPH as _)); /// `IPPROTO_ENCAP` @@ -687,10 +772,17 @@ pub mod ipproto { target_os = "aix", target_os = "espidf", target_os = "haiku", + target_os = "vita", )))] pub const ENCAP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ENCAP as _)); /// `IPPROTO_PIM` - #[cfg(not(any(solarish, target_os = "aix", target_os = "espidf", target_os = "haiku")))] + #[cfg(not(any( + solarish, + target_os = "aix", + target_os = "espidf", + target_os = "haiku", + target_os = "vita" + )))] pub const PIM: Protocol = Protocol(new_raw_protocol(c::IPPROTO_PIM as _)); /// `IPPROTO_COMP` #[cfg(not(any( @@ -700,7 +792,8 @@ pub mod ipproto { target_os = "aix", target_os = "espidf", target_os = "haiku", - target_os = "nto" + target_os = "nto", + target_os = "vita", )))] pub const COMP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_COMP as _)); /// `IPPROTO_SCTP` @@ -709,7 +802,8 @@ pub mod ipproto { target_os = "dragonfly", target_os = "espidf", target_os = "haiku", - target_os = "openbsd" + target_os = "openbsd", + target_os = "vita", )))] pub const SCTP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_SCTP as _)); /// `IPPROTO_UDPLITE` @@ -723,6 +817,7 @@ pub mod ipproto { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const UDPLITE: Protocol = Protocol(new_raw_protocol(c::IPPROTO_UDPLITE as _)); /// `IPPROTO_MPLS` @@ -736,13 +831,14 @@ pub mod ipproto { target_os = "haiku", target_os = "netbsd", target_os = "nto", + target_os = "vita", )))] pub const MPLS: Protocol = Protocol(new_raw_protocol(c::IPPROTO_MPLS as _)); /// `IPPROTO_ETHERNET` #[cfg(linux_kernel)] pub const ETHERNET: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ETHERNET as _)); /// `IPPROTO_RAW` - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] pub const RAW: Protocol = Protocol(new_raw_protocol(c::IPPROTO_RAW as _)); /// `IPPROTO_MPTCP` #[cfg(not(any( @@ -755,10 +851,16 @@ pub mod ipproto { target_os = "fuchsia", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const MPTCP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_MPTCP as _)); /// `IPPROTO_FRAGMENT` - #[cfg(not(any(solarish, target_os = "espidf", target_os = "haiku")))] + #[cfg(not(any( + solarish, + target_os = "espidf", + target_os = "haiku", + target_os = "vita" + )))] pub const FRAGMENT: Protocol = Protocol(new_raw_protocol(c::IPPROTO_FRAGMENT as _)); /// `IPPROTO_ICMPV6` pub const ICMPV6: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ICMPV6 as _)); @@ -772,10 +874,16 @@ pub mod ipproto { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] pub const MH: Protocol = Protocol(new_raw_protocol(c::IPPROTO_MH as _)); /// `IPPROTO_ROUTING` - #[cfg(not(any(solarish, target_os = "espidf", target_os = "haiku")))] + #[cfg(not(any( + solarish, + target_os = "espidf", + target_os = "haiku", + target_os = "vita" + )))] pub const ROUTING: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ROUTING as _)); } @@ -1323,6 +1431,7 @@ bitflags! { target_os = "espidf", target_os = "haiku", target_os = "nto", + target_os = "vita", )))] const NONBLOCK = bitcast!(c::SOCK_NONBLOCK); @@ -1336,6 +1445,25 @@ bitflags! { } } +/// UNIX credentials of socket peer, for use with [`get_socket_peercred`] +/// [`SendAncillaryMessage::ScmCredentials`] and +/// [`RecvAncillaryMessage::ScmCredentials`]. +/// +/// [`get_socket_peercred`]: crate::net::sockopt::get_socket_peercred +/// [`SendAncillaryMessage::ScmCredentials`]: crate::net::SendAncillaryMessage::ScmCredentials +/// [`RecvAncillaryMessage::ScmCredentials`]: crate::net::RecvAncillaryMessage::ScmCredentials +#[cfg(linux_kernel)] +#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] +#[repr(C)] +pub struct UCred { + /// Process ID of peer + pub pid: crate::pid::Pid, + /// User ID of peer + pub uid: crate::ugid::Uid, + /// Group ID of peer + pub gid: crate::ugid::Gid, +} + #[test] fn test_sizes() { use c::c_int; @@ -1361,4 +1489,7 @@ fn test_sizes() { let t: Option<Protocol> = Some(Protocol::from_raw(RawProtocol::new(4567).unwrap())); assert_eq!(4567_u32, transmute::<Option<Protocol>, u32>(t)); } + + #[cfg(linux_kernel)] + assert_eq_size!(UCred, libc::ucred); } diff --git a/vendor/rustix/src/param/auxv.rs b/vendor/rustix/src/param/auxv.rs index 03be2a29d..19f93dc04 100644 --- a/vendor/rustix/src/param/auxv.rs +++ b/vendor/rustix/src/param/auxv.rs @@ -1,12 +1,9 @@ use crate::backend; #[cfg(any( linux_raw, - all( - libc, - any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", - ) + any( + all(target_os = "android", target_pointer_width = "64"), + target_os = "linux", ) ))] use crate::ffi::CStr; @@ -39,7 +36,7 @@ pub fn page_size() -> usize { /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html /// [Linux]: https://man7.org/linux/man-pages/man3/sysconf.3.html -#[cfg(not(target_os = "wasi"))] +#[cfg(not(any(target_os = "vita", target_os = "wasi")))] #[inline] #[doc(alias = "_SC_CLK_TCK")] pub fn clock_ticks_per_second() -> u64 { @@ -58,12 +55,9 @@ pub fn clock_ticks_per_second() -> u64 { /// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html #[cfg(any( linux_raw, - all( - libc, - any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", - ) + any( + all(target_os = "android", target_pointer_width = "64"), + target_os = "linux", ) ))] #[inline] @@ -82,12 +76,9 @@ pub fn linux_hwcap() -> (usize, usize) { /// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html #[cfg(any( linux_raw, - all( - libc, - any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", - ) + any( + all(target_os = "android", target_pointer_width = "64"), + target_os = "linux", ) ))] #[inline] diff --git a/vendor/rustix/src/path/arg.rs b/vendor/rustix/src/path/arg.rs index 3b0ad91ae..4a4c8b30f 100644 --- a/vendor/rustix/src/path/arg.rs +++ b/vendor/rustix/src/path/arg.rs @@ -36,7 +36,7 @@ use {alloc::string::String, alloc::vec::Vec}; /// This is similar to [`AsRef`]`<`[`Path`]`>`, but is implemented for more /// kinds of strings and can convert into more kinds of strings. /// -/// # Example +/// # Examples /// /// ``` /// # #[cfg(any(feature = "fs", feature = "net"))] @@ -1039,7 +1039,7 @@ where buf_ptr.add(bytes.len()).write(0); } - // SAFETY: we just wrote the bytes above and they will remain valid for the + // SAFETY: We just wrote the bytes above and they will remain valid for the // duration of `f` b/c buf doesn't get dropped until the end of the // function. match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) }) { @@ -1078,15 +1078,15 @@ where return Err(io::Errno::NAMETOOLONG); } - // SAFETY: `bytes.len() < LARGE_PATH_BUFFER_SIZE` which means we have space - // for `bytes.len() + 1` u8s: + // SAFETY: `bytes.len() < LARGE_PATH_BUFFER_SIZE` which means we have + // space for `bytes.len() + 1` u8s: unsafe { ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len()); buf_ptr.add(bytes.len()).write(0); } - // SAFETY: we just wrote the bytes above and they will remain valid for the - // duration of `f` b/c buf doesn't get dropped until the end of the + // SAFETY: We just wrote the bytes above and they will remain valid for + // the duration of `f` b/c buf doesn't get dropped until the end of the // function. match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) }) { diff --git a/vendor/rustix/src/path/dec_int.rs b/vendor/rustix/src/path/dec_int.rs index 04c97d406..e9c46f49a 100644 --- a/vendor/rustix/src/path/dec_int.rs +++ b/vendor/rustix/src/path/dec_int.rs @@ -22,7 +22,7 @@ use {core::fmt, std::ffi::OsStr, std::path::Path}; /// /// This is used for opening paths such as `/proc/self/fd/<fd>` on Linux. /// -/// # Example +/// # Examples /// /// ``` /// # #[cfg(any(feature = "fs", feature = "net"))] diff --git a/vendor/rustix/src/pid.rs b/vendor/rustix/src/pid.rs index 3911e4c7a..5f2b9ad2a 100644 --- a/vendor/rustix/src/pid.rs +++ b/vendor/rustix/src/pid.rs @@ -26,8 +26,7 @@ impl Pid { /// Converts a `RawPid` into a `Pid`. /// - /// Returns `Some` for strictly positive `RawPid`s. Otherwise, returns - /// `None`. + /// Returns `Some` for positive `RawPid`s. Otherwise, returns `None`. /// /// This is safe because a `Pid` is a number without any guarantees for the /// kernel. Non-child `Pid`s are always racy for any syscalls, but can only @@ -39,18 +38,18 @@ impl Pid { #[inline] pub const fn from_raw(raw: RawPid) -> Option<Self> { if raw > 0 { - // SAFETY: raw > 0. + // SAFETY: We just checked that `raw > 0`. unsafe { Some(Self::from_raw_unchecked(raw)) } } else { None } } - /// Converts a known strictly positive `RawPid` into a `Pid`. + /// Converts a known positive `RawPid` into a `Pid`. /// /// # Safety /// - /// The caller must guarantee `raw` is strictly positive. + /// The caller must guarantee `raw` is positive. #[inline] pub const unsafe fn from_raw_unchecked(raw: RawPid) -> Self { debug_assert!(raw > 0); diff --git a/vendor/rustix/src/pipe.rs b/vendor/rustix/src/pipe.rs index 2a45b7a9d..5f0175c85 100644 --- a/vendor/rustix/src/pipe.rs +++ b/vendor/rustix/src/pipe.rs @@ -14,6 +14,7 @@ use crate::{backend, io}; target_os = "espidf", target_os = "haiku", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] use backend::c; @@ -39,7 +40,9 @@ pub use backend::pipe::types::{IoSliceRaw, SpliceFlags}; windows, target_os = "espidf", target_os = "haiku", + target_os = "hurd", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] pub const PIPE_BUF: usize = c::PIPE_BUF; @@ -153,9 +156,9 @@ pub fn splice<FdIn: AsFd, FdOut: AsFd>( /// the pipe is placed in `fd`. /// /// Additionally if `SpliceFlags::GIFT` is set, the caller must also ensure -/// that the contents of `bufs` in never modified following the call, -/// and that all of the pointers in `bufs` are page aligned, -/// and the lengths are multiples of a page size in bytes. +/// that the contents of `bufs` in never modified following the call, and that +/// all of the pointers in `bufs` are page aligned, and the lengths are +/// multiples of a page size in bytes. /// /// # References /// - [Linux] diff --git a/vendor/rustix/src/prctl.rs b/vendor/rustix/src/prctl.rs index 6aedf3018..0ea83031b 100644 --- a/vendor/rustix/src/prctl.rs +++ b/vendor/rustix/src/prctl.rs @@ -26,7 +26,7 @@ bitflags! { /// `PR_PAC_APGAKEY`—Generic authentication `A` key. const GENERIC_AUTHENTICATION_KEY_A = linux_raw_sys::prctl::PR_PAC_APGAKEY; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/process/chdir.rs b/vendor/rustix/src/process/chdir.rs index b110afef8..a68352f0e 100644 --- a/vendor/rustix/src/process/chdir.rs +++ b/vendor/rustix/src/process/chdir.rs @@ -67,15 +67,18 @@ fn _getcwd(mut buffer: Vec<u8>) -> io::Result<CString> { loop { match backend::process::syscalls::getcwd(buffer.spare_capacity_mut()) { Err(io::Errno::RANGE) => { - buffer.reserve(buffer.capacity() + 1); // use `Vec` reallocation strategy to grow capacity exponentially + // Use `Vec` reallocation strategy to grow capacity + // exponentially. + buffer.reserve(buffer.capacity() + 1); } Ok(_) => { // SAFETY: // - "These functions return a null-terminated string" - // - [POSIX definition 3.375: String]: "A contiguous sequence of bytes - // terminated by and including the first null byte." + // - [POSIX definition 3.375: String]: "A contiguous sequence + // of bytes terminated by and including the first null byte." // - // Thus, there will be a single NUL byte at the end of the string. + // Thus, there will be a single NUL byte at the end of the + // string. // // [POSIX definition 3.375: String]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_375 unsafe { diff --git a/vendor/rustix/src/process/id.rs b/vendor/rustix/src/process/id.rs index 4ed33a6c8..1a49dc539 100644 --- a/vendor/rustix/src/process/id.rs +++ b/vendor/rustix/src/process/id.rs @@ -225,7 +225,8 @@ pub fn getgroups() -> io::Result<Vec<Gid>> { buffer.resize(ngroups, Gid::ROOT); return Ok(buffer); } - buffer.reserve(1); // use `Vec` reallocation strategy to grow capacity exponentially + // Use `Vec` reallocation strategy to grow capacity exponentially. + buffer.reserve(1); buffer.resize(buffer.capacity(), Gid::ROOT); } } diff --git a/vendor/rustix/src/process/ioctl.rs b/vendor/rustix/src/process/ioctl.rs index 3c9d90255..5afc76609 100644 --- a/vendor/rustix/src/process/ioctl.rs +++ b/vendor/rustix/src/process/ioctl.rs @@ -10,7 +10,7 @@ use crate::{backend, io, ioctl}; use backend::c; use backend::fd::AsFd; -/// `ioctl(fd, TIOCSCTTY, 0)`—Sets the controlling terminal for the processs. +/// `ioctl(fd, TIOCSCTTY, 0)`—Sets the controlling terminal for the process. /// /// # References /// - [Linux] diff --git a/vendor/rustix/src/process/kill.rs b/vendor/rustix/src/process/kill.rs index 5f6f06c48..01d5380f8 100644 --- a/vendor/rustix/src/process/kill.rs +++ b/vendor/rustix/src/process/kill.rs @@ -19,8 +19,8 @@ pub fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> { /// `kill(-pid, sig)`—Sends a signal to all processes in a process group. /// -/// If `pid` is 1, this sends a signal to all processes the current process -/// has permission to send signals to, except process `1`, possibly other +/// If `pid` is 1, this sends a signal to all processes the current process has +/// permission to send signals to, except process `1`, possibly other /// system-specific processes, and on some systems, the current process. /// /// # References diff --git a/vendor/rustix/src/process/membarrier.rs b/vendor/rustix/src/process/membarrier.rs index 9c42bbd85..26be07dd9 100644 --- a/vendor/rustix/src/process/membarrier.rs +++ b/vendor/rustix/src/process/membarrier.rs @@ -35,7 +35,7 @@ bitflags::bitflags! { /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) const REGISTER_PRIVATE_EXPEDITED_RSEQ = MembarrierCommand::RegisterPrivateExpeditedRseq as _; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/process/mod.rs b/vendor/rustix/src/process/mod.rs index 55eed1ac8..195216c3a 100644 --- a/vendor/rustix/src/process/mod.rs +++ b/vendor/rustix/src/process/mod.rs @@ -7,7 +7,7 @@ mod chroot; mod exit; #[cfg(not(target_os = "wasi"))] // WASI doesn't have get[gpu]id. mod id; -#[cfg(not(any(target_os = "aix", target_os = "espidf")))] +#[cfg(not(any(target_os = "aix", target_os = "espidf", target_os = "vita")))] mod ioctl; #[cfg(not(any(target_os = "espidf", target_os = "wasi")))] mod kill; @@ -19,7 +19,8 @@ mod pidfd; mod pidfd_getfd; #[cfg(linux_kernel)] mod prctl; -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] // WASI doesn't have [gs]etpriority. +#[cfg(not(any(target_os = "fuchsia", target_os = "vita", target_os = "wasi")))] +// WASI doesn't have [gs]etpriority. mod priority; #[cfg(freebsdlike)] mod procctl; @@ -27,6 +28,7 @@ mod procctl; target_os = "espidf", target_os = "fuchsia", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] mod rlimit; @@ -35,7 +37,7 @@ mod sched; mod sched_yield; #[cfg(not(target_os = "wasi"))] // WASI doesn't have umask. mod umask; -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] +#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] mod wait; #[cfg(not(target_os = "wasi"))] @@ -45,7 +47,7 @@ pub use chroot::*; pub use exit::*; #[cfg(not(target_os = "wasi"))] pub use id::*; -#[cfg(not(any(target_os = "aix", target_os = "espidf")))] +#[cfg(not(any(target_os = "aix", target_os = "espidf", target_os = "vita")))] pub use ioctl::*; #[cfg(not(any(target_os = "espidf", target_os = "wasi")))] pub use kill::*; @@ -57,7 +59,7 @@ pub use pidfd::*; pub use pidfd_getfd::*; #[cfg(linux_kernel)] pub use prctl::*; -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] +#[cfg(not(any(target_os = "fuchsia", target_os = "vita", target_os = "wasi")))] pub use priority::*; #[cfg(freebsdlike)] pub use procctl::*; @@ -65,6 +67,7 @@ pub use procctl::*; target_os = "espidf", target_os = "fuchsia", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] pub use rlimit::*; @@ -73,5 +76,5 @@ pub use sched::*; pub use sched_yield::sched_yield; #[cfg(not(target_os = "wasi"))] pub use umask::*; -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] +#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] pub use wait::*; diff --git a/vendor/rustix/src/process/pidfd.rs b/vendor/rustix/src/process/pidfd.rs index 0548055fc..abebaf21f 100644 --- a/vendor/rustix/src/process/pidfd.rs +++ b/vendor/rustix/src/process/pidfd.rs @@ -12,7 +12,7 @@ bitflags::bitflags! { /// `PIDFD_NONBLOCK`. const NONBLOCK = backend::c::PIDFD_NONBLOCK; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/process/pidfd_getfd.rs b/vendor/rustix/src/process/pidfd_getfd.rs index 27d4f1986..4c7696fb6 100644 --- a/vendor/rustix/src/process/pidfd_getfd.rs +++ b/vendor/rustix/src/process/pidfd_getfd.rs @@ -18,7 +18,7 @@ bitflags::bitflags! { #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct PidfdGetfdFlags: backend::c::c_uint { - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/process/prctl.rs b/vendor/rustix/src/process/prctl.rs index 59be7020f..830abc13d 100644 --- a/vendor/rustix/src/process/prctl.rs +++ b/vendor/rustix/src/process/prctl.rs @@ -149,7 +149,7 @@ bitflags! { #[doc(alias = "PR_UNALIGN_SIGBUS")] const SIGBUS = 2; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -410,8 +410,8 @@ const PR_SET_ENDIAN: c_int = 20; /// /// # Safety /// -/// Please ensure the conditions necessary to safely call this function, -/// as detailed in the references above. +/// Please ensure the conditions necessary to safely call this function, as +/// detailed in the references above. /// /// [`prctl(PR_SET_ENDIAN,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] @@ -649,8 +649,8 @@ pub enum VirtualMemoryMapAddress { /// /// # Safety /// -/// Please ensure the conditions necessary to safely call this function, -/// as detailed in the references above. +/// Please ensure the conditions necessary to safely call this function, as +/// detailed in the references above. /// /// [`prctl(PR_SET_MM,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] @@ -685,8 +685,8 @@ pub fn set_executable_file(fd: BorrowedFd<'_>) -> io::Result<()> { /// /// # Safety /// -/// Please ensure the conditions necessary to safely call this function, -/// as detailed in the references above. +/// Please ensure the conditions necessary to safely call this function, as +/// detailed in the references above. /// /// [`prctl(PR_SET_MM,PR_SET_MM_AUXV,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] @@ -764,8 +764,8 @@ pub struct PrctlMmMap { /// /// # Safety /// -/// Please ensure the conditions necessary to safely call this function, -/// as detailed in the references above. +/// Please ensure the conditions necessary to safely call this function, as +/// detailed in the references above. /// /// [`prctl(PR_SET_MM,PR_SET_MM_MAP,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] @@ -960,9 +960,11 @@ bitflags! { const ENABLE = 1_u32 << 1; /// The speculation feature is disabled, mitigation is enabled. const DISABLE = 1_u32 << 2; - /// The speculation feature is disabled, mitigation is enabled, and it cannot be undone. + /// The speculation feature is disabled, mitigation is enabled, and it + /// cannot be undone. const FORCE_DISABLE = 1_u32 << 3; - /// The speculation feature is disabled, mitigation is enabled, and the state will be cleared on `execve`. + /// The speculation feature is disabled, mitigation is enabled, and the + /// state will be cleared on `execve`. const DISABLE_NOEXEC = 1_u32 << 4; } } @@ -972,15 +974,18 @@ bitflags! { #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct SpeculationFeatureState: u32 { - /// Mitigation can be controlled per thread by `PR_SET_SPECULATION_CTRL`. + /// Mitigation can be controlled per thread by + /// `PR_SET_SPECULATION_CTRL`. const PRCTL = 1_u32 << 0; /// The speculation feature is enabled, mitigation is disabled. const ENABLE = 1_u32 << 1; /// The speculation feature is disabled, mitigation is enabled. const DISABLE = 1_u32 << 2; - /// The speculation feature is disabled, mitigation is enabled, and it cannot be undone. + /// The speculation feature is disabled, mitigation is enabled, and it + /// cannot be undone. const FORCE_DISABLE = 1_u32 << 3; - /// The speculation feature is disabled, mitigation is enabled, and the state will be cleared on `execve`. + /// The speculation feature is disabled, mitigation is enabled, and the + /// state will be cleared on `execve`. const DISABLE_NOEXEC = 1_u32 << 4; } } @@ -1080,8 +1085,8 @@ const PR_PAC_SET_ENABLED_KEYS: c_int = 60; /// /// # Safety /// -/// Please ensure the conditions necessary to safely call this function, -/// as detailed in the references above. +/// Please ensure the conditions necessary to safely call this function, as +/// detailed in the references above. /// /// [`prctl(PR_PAC_SET_ENABLED_KEYS,...)`]: https://www.kernel.org/doc/html/v5.18/arm64/pointer-authentication.html #[inline] diff --git a/vendor/rustix/src/process/procctl.rs b/vendor/rustix/src/process/procctl.rs index 5225f16f7..f06bd72d6 100644 --- a/vendor/rustix/src/process/procctl.rs +++ b/vendor/rustix/src/process/procctl.rs @@ -230,7 +230,7 @@ bitflags! { /// The process is the root of the reaper tree (pid 1). const REALINIT = 2; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -300,7 +300,8 @@ bitflags! { const REAPER = 4; /// The reported process is in the zombie state. const ZOMBIE = 8; - /// The reported process is stopped by SIGSTOP/SIGTSTP. + /// The reported process is stopped by + /// [`Signal::Stop`]/[`Signal::Tstp`]. const STOPPED = 16; /// The reported process is in the process of exiting. const EXITING = 32; @@ -493,12 +494,12 @@ const PROC_NO_NEW_PRIVS_CTL: c_int = 19; const PROC_NO_NEW_PRIVS_ENABLE: c_int = 1; -/// Enable the `no_new_privs` mode that ignores SUID and SGID bits -/// on `execve` in the specified process and its future descendants. +/// Enable the `no_new_privs` mode that ignores SUID and SGID bits on `execve` +/// in the specified process and its future descendants. /// -/// This is similar to `set_no_new_privs` on Linux, with the exception -/// that on FreeBSD there is no argument `no_new_privs` argument as it's -/// only possible to enable this mode and there's no going back. +/// This is similar to `set_no_new_privs` on Linux, with the exception that on +/// FreeBSD there is no argument `no_new_privs` argument as it's only possible +/// to enable this mode and there's no going back. /// /// # References /// - [Linux: `prctl(PR_SET_NO_NEW_PRIVS,...)`] diff --git a/vendor/rustix/src/process/sched.rs b/vendor/rustix/src/process/sched.rs index 239b7df82..b7dcd58cc 100644 --- a/vendor/rustix/src/process/sched.rs +++ b/vendor/rustix/src/process/sched.rs @@ -80,8 +80,8 @@ impl Default for CpuSet { /// `pid` is the thread ID to update. If pid is `None`, then the current thread /// is updated. /// -/// The `CpuSet` argument specifies the set of CPUs on which the thread will -/// be eligible to run. +/// The `CpuSet` argument specifies the set of CPUs on which the thread will be +/// eligible to run. /// /// # References /// - [Linux] diff --git a/vendor/rustix/src/process/wait.rs b/vendor/rustix/src/process/wait.rs index b43bd03d6..ccb90ae43 100644 --- a/vendor/rustix/src/process/wait.rs +++ b/vendor/rustix/src/process/wait.rs @@ -9,7 +9,7 @@ use crate::fd::BorrowedFd; use crate::backend::process::wait::SiginfoExt; bitflags! { - /// Options for modifying the behavior of wait/waitpid + /// Options for modifying the behavior of [`wait`]/[`waitpid`]. #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct WaitOptions: u32 { @@ -23,14 +23,14 @@ bitflags! { /// [`Signal::Cont`]. const CONTINUED = bitcast!(backend::process::wait::WCONTINUED); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } #[cfg(not(any(target_os = "openbsd", target_os = "redox", target_os = "wasi")))] bitflags! { - /// Options for modifying the behavior of waitid + /// Options for modifying the behavior of [`waitid`]. #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct WaitidOptions: u32 { @@ -46,7 +46,7 @@ bitflags! { /// Wait for processes that have been stopped. const STOPPED = bitcast!(backend::process::wait::WSTOPPED); - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -93,8 +93,8 @@ impl WaitStatus { backend::process::wait::WIFCONTINUED(self.0 as _) } - /// Returns the number of the signal that stopped the process, - /// if the process was stopped by a signal. + /// Returns the number of the signal that stopped the process, if the + /// process was stopped by a signal. #[inline] pub fn stopping_signal(self) -> Option<u32> { if self.stopped() { @@ -104,8 +104,8 @@ impl WaitStatus { } } - /// Returns the exit status number returned by the process, - /// if it exited normally. + /// Returns the exit status number returned by the process, if it exited + /// normally. #[inline] pub fn exit_status(self) -> Option<u32> { if self.exited() { @@ -115,8 +115,8 @@ impl WaitStatus { } } - /// Returns the number of the signal that terminated the process, - /// if the process was terminated by a signal. + /// Returns the number of the signal that terminated the process, if the + /// process was terminated by a signal. #[inline] pub fn terminating_signal(self) -> Option<u32> { if self.signaled() { @@ -153,15 +153,15 @@ impl WaitidStatus { self.si_code() == backend::c::CLD_EXITED } - /// Returns whether the process was terminated by a signal - /// and did not create a core file. + /// Returns whether the process was terminated by a signal and did not + /// create a core file. #[inline] pub fn killed(&self) -> bool { self.si_code() == backend::c::CLD_KILLED } - /// Returns whether the process was terminated by a signal - /// and did create a core file. + /// Returns whether the process was terminated by a signal and did create a + /// core file. #[inline] pub fn dumped(&self) -> bool { self.si_code() == backend::c::CLD_DUMPED @@ -173,8 +173,8 @@ impl WaitidStatus { self.si_code() == backend::c::CLD_CONTINUED } - /// Returns the number of the signal that stopped the process, - /// if the process was stopped by a signal. + /// Returns the number of the signal that stopped the process, if the + /// process was stopped by a signal. #[inline] #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] pub fn stopping_signal(&self) -> Option<u32> { @@ -185,8 +185,8 @@ impl WaitidStatus { } } - /// Returns the number of the signal that trapped the process, - /// if the process was trapped by a signal. + /// Returns the number of the signal that trapped the process, if the + /// process was trapped by a signal. #[inline] #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] pub fn trapping_signal(&self) -> Option<u32> { @@ -197,8 +197,8 @@ impl WaitidStatus { } } - /// Returns the exit status number returned by the process, - /// if it exited normally. + /// Returns the exit status number returned by the process, if it exited + /// normally. #[inline] #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] pub fn exit_status(&self) -> Option<u32> { @@ -209,8 +209,8 @@ impl WaitidStatus { } } - /// Returns the number of the signal that terminated the process, - /// if the process was terminated by a signal. + /// Returns the number of the signal that terminated the process, if the + /// process was terminated by a signal. #[inline] #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] pub fn terminating_signal(&self) -> Option<u32> { @@ -254,20 +254,26 @@ impl WaitidStatus { #[non_exhaustive] pub enum WaitId<'a> { /// Wait on all processes. + #[doc(alias = "P_ALL")] All, /// Wait for a specific process ID. + #[doc(alias = "P_PID")] Pid(Pid), + /// Wait for a specific process group ID, or the calling process' group ID. + #[doc(alias = "P_PGID")] + Pgid(Option<Pid>), + /// Wait for a specific process file descriptor. #[cfg(target_os = "linux")] + #[doc(alias = "P_PIDFD")] PidFd(BorrowedFd<'a>), /// Eat the lifetime for non-Linux platforms. #[doc(hidden)] #[cfg(not(target_os = "linux"))] __EatLifetime(core::marker::PhantomData<&'a ()>), - // TODO(notgull): Once this crate has the concept of PGIDs, add a WaitId::Pgid } /// `waitpid(pid, waitopts)`—Wait for a specific process to change state. @@ -275,12 +281,6 @@ pub enum WaitId<'a> { /// If the pid is `None`, the call will wait for any child process whose /// process group id matches that of the calling process. /// -/// If the pid is equal to `RawPid::MAX`, the call will wait for any child -/// process. -/// -/// Otherwise if the `wrapping_neg` of pid is less than pid, the call will wait -/// for any child process with a group ID equal to the `wrapping_neg` of `pid`. -/// /// Otherwise, the call will wait for the child process with the given pid. /// /// On Success, returns the status of the selected process. @@ -288,6 +288,16 @@ pub enum WaitId<'a> { /// If `NOHANG` was specified in the options, and the selected child process /// didn't change state, returns `None`. /// +/// # Bugs +/// +/// This function does not currently support waiting for given process group +/// (the < 0 case of `waitpid`); to do that, currently the [`waitpgid`] or +/// [`waitid`] function must be used. +/// +/// This function does not currently support waiting for any process (the +/// `-1` case of `waitpid`); to do that, currently the [`wait`] function must +/// be used. +/// /// # References /// - [POSIX] /// - [Linux] @@ -300,6 +310,28 @@ pub fn waitpid(pid: Option<Pid>, waitopts: WaitOptions) -> io::Result<Option<Wai Ok(backend::process::syscalls::waitpid(pid, waitopts)?.map(|(_, status)| status)) } +/// `waitpid(-pgid, waitopts)`—Wait for a process in a specific process group +/// to change state. +/// +/// The call will wait for any child process with the given pgid. +/// +/// On Success, returns the status of the selected process. +/// +/// If `NOHANG` was specified in the options, and no selected child process +/// changed state, returns `None`. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html +/// [Linux]: https://man7.org/linux/man-pages/man2/waitpid.2.html +#[cfg(not(target_os = "wasi"))] +#[inline] +pub fn waitpgid(pgid: Pid, waitopts: WaitOptions) -> io::Result<Option<WaitStatus>> { + Ok(backend::process::syscalls::waitpgid(pgid, waitopts)?.map(|(_, status)| status)) +} + /// `wait(waitopts)`—Wait for any of the children of calling process to /// change state. /// diff --git a/vendor/rustix/src/procfs.rs b/vendor/rustix/src/procfs.rs index 14ad631a7..fb35a2028 100644 --- a/vendor/rustix/src/procfs.rs +++ b/vendor/rustix/src/procfs.rs @@ -18,20 +18,19 @@ //! namespace. So with the checking here, they may fail, but they won't be able //! to succeed with bogus results. -use crate::backend::pid::syscalls::getpid; use crate::fd::{AsFd, BorrowedFd, OwnedFd}; +use crate::ffi::CStr; use crate::fs::{ - fstat, fstatfs, major, openat, renameat, FileType, FsWord, Mode, OFlags, Stat, CWD, + fstat, fstatfs, major, openat, renameat, FileType, FsWord, Mode, OFlags, RawDir, Stat, CWD, PROC_SUPER_MAGIC, }; use crate::io; use crate::path::DecInt; #[cfg(feature = "rustc-dep-of-std")] use core::lazy::OnceCell; +use core::mem::MaybeUninit; #[cfg(not(feature = "rustc-dep-of-std"))] use once_cell::sync::OnceCell; -#[cfg(feature = "alloc")] -use {crate::ffi::CStr, crate::fs::Dir}; /// Linux's procfs always uses inode 1 for its root directory. const PROC_ROOT_INO: u64 = 1; @@ -42,8 +41,8 @@ enum Kind { Proc, Pid, Fd, - #[cfg(feature = "alloc")] File, + Symlink, } /// Check a subdirectory of "/proc" for anomalies. @@ -69,16 +68,23 @@ fn check_proc_entry_with_stat( match kind { Kind::Proc => check_proc_root(entry, &entry_stat)?, Kind::Pid | Kind::Fd => check_proc_subdir(entry, &entry_stat, proc_stat)?, - #[cfg(feature = "alloc")] Kind::File => check_proc_file(&entry_stat, proc_stat)?, + Kind::Symlink => check_proc_symlink(&entry_stat, proc_stat)?, } // "/proc" directories are typically mounted r-xr-xr-x. // "/proc/self/fd" is r-x------. Allow them to have fewer permissions, but // not more. - let expected_mode = if let Kind::Fd = kind { 0o500 } else { 0o555 }; - if entry_stat.st_mode & 0o777 & !expected_mode != 0 { - return Err(io::Errno::NOTSUP); + match kind { + Kind::Symlink => { + // On Linux, symlinks don't have their own permissions. + } + _ => { + let expected_mode = if let Kind::Fd = kind { 0o500 } else { 0o555 }; + if entry_stat.st_mode & 0o777 & !expected_mode != 0 { + return Err(io::Errno::NOTSUP); + } + } } match kind { @@ -97,7 +103,6 @@ fn check_proc_entry_with_stat( return Err(io::Errno::NOTSUP); } } - #[cfg(feature = "alloc")] Kind::File => { // Check that files in procfs don't have extraneous hard links to // them (which might indicate hard links to other things). @@ -105,6 +110,13 @@ fn check_proc_entry_with_stat( return Err(io::Errno::NOTSUP); } } + Kind::Symlink => { + // Check that symlinks in procfs don't have extraneous hard links + // to them (which might indicate hard links to other things). + if entry_stat.st_nlink != 1 { + return Err(io::Errno::NOTSUP); + } + } } Ok(entry_stat) @@ -153,7 +165,6 @@ fn check_proc_subdir( Ok(()) } -#[cfg(feature = "alloc")] fn check_proc_file(stat: &Stat, proc_stat: Option<&Stat>) -> io::Result<()> { // Check that we have a regular file. if FileType::from_raw_mode(stat.st_mode) != FileType::RegularFile { @@ -165,6 +176,17 @@ fn check_proc_file(stat: &Stat, proc_stat: Option<&Stat>) -> io::Result<()> { Ok(()) } +fn check_proc_symlink(stat: &Stat, proc_stat: Option<&Stat>) -> io::Result<()> { + // Check that we have a symbolic link. + if FileType::from_raw_mode(stat.st_mode) != FileType::Symlink { + return Err(io::Errno::NOTSUP); + } + + check_proc_nonroot(stat, proc_stat)?; + + Ok(()) +} + fn check_proc_nonroot(stat: &Stat, proc_stat: Option<&Stat>) -> io::Result<()> { // Check that we haven't been linked back to the root of "/proc". if stat.st_ino == PROC_ROOT_INO { @@ -245,6 +267,7 @@ fn proc() -> io::Result<(BorrowedFd<'static>, &'static Stat)> { /// - [Linux] /// /// [Linux]: https://man7.org/linux/man-pages/man5/proc.5.html +#[allow(unsafe_code)] fn proc_self() -> io::Result<(BorrowedFd<'static>, &'static Stat)> { static PROC_SELF: StaticFd = StaticFd::new(); @@ -253,11 +276,21 @@ fn proc_self() -> io::Result<(BorrowedFd<'static>, &'static Stat)> { .get_or_try_init(|| { let (proc, proc_stat) = proc()?; - let pid = getpid(); + // `getpid` would return our pid in our own pid namespace, so + // instead use `readlink` on the `self` symlink to learn our pid in + // the procfs namespace. + let self_symlink = open_and_check_file(proc, proc_stat, cstr!("self"), Kind::Symlink)?; + let mut buf = [MaybeUninit::<u8>::uninit(); 20]; + let len = crate::backend::fs::syscalls::readlinkat( + self_symlink.as_fd(), + cstr!(""), + &mut buf, + )?; + let pid: &[u8] = unsafe { core::mem::transmute(&buf[..len]) }; // Open "/proc/self". Use our pid to compute the name rather than // literally using "self", as "self" is a symlink. - let proc_self = proc_opendirat(proc, DecInt::new(pid.as_raw_nonzero().get()))?; + let proc_self = proc_opendirat(proc, pid)?; let proc_self_stat = check_proc_entry(Kind::Pid, proc_self.as_fd(), Some(proc_stat)) .map_err(|_err| io::Errno::NOTSUP)?; @@ -314,7 +347,6 @@ fn new_static_fd(fd: OwnedFd, stat: Stat) -> (OwnedFd, Stat) { /// - [Linux] /// /// [Linux]: https://man7.org/linux/man-pages/man5/proc.5.html -#[cfg(feature = "alloc")] fn proc_self_fdinfo() -> io::Result<(BorrowedFd<'static>, &'static Stat)> { static PROC_SELF_FDINFO: StaticFd = StaticFd::new(); @@ -344,18 +376,21 @@ fn proc_self_fdinfo() -> io::Result<(BorrowedFd<'static>, &'static Stat)> { /// - [Linux] /// /// [Linux]: https://man7.org/linux/man-pages/man5/proc.5.html -#[cfg(feature = "alloc")] #[inline] #[cfg_attr(doc_cfg, doc(cfg(feature = "procfs")))] pub fn proc_self_fdinfo_fd<Fd: AsFd>(fd: Fd) -> io::Result<OwnedFd> { _proc_self_fdinfo(fd.as_fd()) } -#[cfg(feature = "alloc")] fn _proc_self_fdinfo(fd: BorrowedFd<'_>) -> io::Result<OwnedFd> { let (proc_self_fdinfo, proc_self_fdinfo_stat) = proc_self_fdinfo()?; let fd_str = DecInt::from_fd(fd); - open_and_check_file(proc_self_fdinfo, proc_self_fdinfo_stat, fd_str.as_c_str()) + open_and_check_file( + proc_self_fdinfo, + proc_self_fdinfo_stat, + fd_str.as_c_str(), + Kind::File, + ) } /// Returns a handle to a Linux `/proc/self/pagemap` file. @@ -369,7 +404,6 @@ fn _proc_self_fdinfo(fd: BorrowedFd<'_>) -> io::Result<OwnedFd> { /// /// [Linux]: https://man7.org/linux/man-pages/man5/proc.5.html /// [Linux pagemap]: https://www.kernel.org/doc/Documentation/vm/pagemap.txt -#[cfg(feature = "alloc")] #[inline] #[cfg_attr(doc_cfg, doc(cfg(feature = "procfs")))] pub fn proc_self_pagemap() -> io::Result<OwnedFd> { @@ -385,7 +419,6 @@ pub fn proc_self_pagemap() -> io::Result<OwnedFd> { /// - [Linux] /// /// [Linux]: https://man7.org/linux/man-pages/man5/proc.5.html -#[cfg(feature = "alloc")] #[inline] #[cfg_attr(doc_cfg, doc(cfg(feature = "procfs")))] pub fn proc_self_maps() -> io::Result<OwnedFd> { @@ -401,7 +434,6 @@ pub fn proc_self_maps() -> io::Result<OwnedFd> { /// - [Linux] /// /// [Linux]: https://man7.org/linux/man-pages/man5/proc.5.html -#[cfg(feature = "alloc")] #[inline] #[cfg_attr(doc_cfg, doc(cfg(feature = "procfs")))] pub fn proc_self_status() -> io::Result<OwnedFd> { @@ -409,15 +441,18 @@ pub fn proc_self_status() -> io::Result<OwnedFd> { } /// Open a file under `/proc/self`. -#[cfg(feature = "alloc")] fn proc_self_file(name: &CStr) -> io::Result<OwnedFd> { let (proc_self, proc_self_stat) = proc_self()?; - open_and_check_file(proc_self, proc_self_stat, name) + open_and_check_file(proc_self, proc_self_stat, name, Kind::File) } /// Open a procfs file within in `dir` and check it for bind mounts. -#[cfg(feature = "alloc")] -fn open_and_check_file(dir: BorrowedFd<'_>, dir_stat: &Stat, name: &CStr) -> io::Result<OwnedFd> { +fn open_and_check_file( + dir: BorrowedFd<'_>, + dir_stat: &Stat, + name: &CStr, + kind: Kind, +) -> io::Result<OwnedFd> { let (_, proc_stat) = proc()?; // Don't use `NOATIME`, because it [requires us to own the file], and when @@ -426,7 +461,11 @@ fn open_and_check_file(dir: BorrowedFd<'_>, dir_stat: &Stat, name: &CStr) -> io: // // [requires us to own the file]: https://man7.org/linux/man-pages/man2/openat.2.html // [to root:root]: https://man7.org/linux/man-pages/man5/proc.5.html - let oflags = OFlags::RDONLY | OFlags::CLOEXEC | OFlags::NOFOLLOW | OFlags::NOCTTY; + let mut oflags = OFlags::RDONLY | OFlags::CLOEXEC | OFlags::NOFOLLOW | OFlags::NOCTTY; + if let Kind::Symlink = kind { + // Open symlinks with `O_PATH`. + oflags |= OFlags::PATH; + } let file = openat(dir, name, oflags, Mode::empty()).map_err(|_err| io::Errno::NOTSUP)?; let file_stat = fstat(&file)?; @@ -436,32 +475,29 @@ fn open_and_check_file(dir: BorrowedFd<'_>, dir_stat: &Stat, name: &CStr) -> io: // we just opened. If we can't find it, there could be a file bind mount on // top of the file we want. // - // As we scan, we also check for ".", to make sure it's the same directory - // as our original directory, to detect mount points, since - // `Dir::read_from` reopens ".". - // // TODO: With Linux 5.8 we might be able to use `statx` and // `STATX_ATTR_MOUNT_ROOT` to detect mountpoints directly instead of doing // this scanning. - let dir = Dir::read_from(dir).map_err(|_err| io::Errno::NOTSUP)?; - // Confirm that we got the same inode. - let dot_stat = dir.stat().map_err(|_err| io::Errno::NOTSUP)?; - if (dot_stat.st_dev, dot_stat.st_ino) != (dir_stat.st_dev, dir_stat.st_ino) { - return Err(io::Errno::NOTSUP); - } + let expected_type = match kind { + Kind::File => FileType::RegularFile, + Kind::Symlink => FileType::Symlink, + _ => unreachable!(), + }; let mut found_file = false; let mut found_dot = false; - for entry in dir { + + let mut buf = [MaybeUninit::uninit(); 2048]; + let mut iter = RawDir::new(dir, &mut buf); + while let Some(entry) = iter.next() { let entry = entry.map_err(|_err| io::Errno::NOTSUP)?; if entry.ino() == file_stat.st_ino - && entry.file_type() == FileType::RegularFile + && entry.file_type() == expected_type && entry.file_name() == name { // We found the file. Proceed to check the file handle. - let _ = - check_proc_entry_with_stat(Kind::File, file.as_fd(), file_stat, Some(proc_stat))?; + let _ = check_proc_entry_with_stat(kind, file.as_fd(), file_stat, Some(proc_stat))?; found_file = true; } else if entry.ino() == dir_stat.st_ino diff --git a/vendor/rustix/src/pty.rs b/vendor/rustix/src/pty.rs index a63fbfeef..926ebf789 100644 --- a/vendor/rustix/src/pty.rs +++ b/vendor/rustix/src/pty.rs @@ -23,7 +23,7 @@ use crate::{fd::FromRawFd, ioctl}; bitflags::bitflags! { /// `O_*` flags for use with [`openpt`] and [`ioctl_tiocgptpeer`]. /// - /// [`ioctl_tiocgtpeer`]: https://docs.rs/rustix/*/x86_64-unknown-linux-gnu/rustix/pty/fn.ioctl_tiocgtpeer.html + /// [`ioctl_tiocgptpeer`]: https://docs.rs/rustix/*/x86_64-unknown-linux-gnu/rustix/pty/fn.ioctl_tiocgptpeer.html #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct OpenptFlags: u32 { @@ -31,7 +31,7 @@ bitflags::bitflags! { const RDWR = c::O_RDWR as c::c_uint; /// `O_NOCTTY` - #[cfg(not(any(target_os = "espidf", target_os = "l4re", target_os = "redox")))] + #[cfg(not(any(target_os = "espidf", target_os = "l4re", target_os = "redox", target_os = "vita")))] const NOCTTY = c::O_NOCTTY as c::c_uint; /// `O_CLOEXEC` @@ -41,7 +41,7 @@ bitflags::bitflags! { #[cfg(any(linux_kernel, target_os = "freebsd", target_os = "netbsd"))] const CLOEXEC = c::O_CLOEXEC as c::c_uint; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -142,8 +142,8 @@ pub fn unlockpt<Fd: AsFd>(fd: Fd) -> io::Result<()> { /// /// On Linux, calling this function has no effect, as the kernel is expected to /// grant the appropriate access. On all other platorms, this function has -/// unspecified behavior if the calling process has a `SIGCHLD` signal handler -/// installed. +/// unspecified behavior if the calling process has a [`Signal::Child`] signal +/// handler installed. /// /// # References /// - [POSIX] @@ -153,6 +153,7 @@ pub fn unlockpt<Fd: AsFd>(fd: Fd) -> io::Result<()> { /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/grantpt.html /// [Linux]: https://man7.org/linux/man-pages/man3/grantpt.3.html /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Allocation.html#index-grantpt +/// [`Signal::Child`]: crate::process::Signal::Child #[inline] pub fn grantpt<Fd: AsFd>(fd: Fd) -> io::Result<()> { #[cfg(not(linux_kernel))] diff --git a/vendor/rustix/src/runtime.rs b/vendor/rustix/src/runtime.rs index 2cb0eba54..3c754a62f 100644 --- a/vendor/rustix/src/runtime.rs +++ b/vendor/rustix/src/runtime.rs @@ -4,7 +4,7 @@ //! Do not use the functions in this module unless you've read all of their //! code. They don't always behave the same way as functions with similar names //! in `libc`. Sometimes information about the differences is included in the -//! Linux documentation under "C library/kernel differences" sections. And, if +//! Linux documentation under “C library/kernel differences” sections. And, if //! there is a libc in the process, these functions may have surprising //! interactions with it. //! @@ -89,7 +89,7 @@ pub unsafe fn arm_set_tls(data: *mut c_void) -> io::Result<()> { backend::runtime::syscalls::tls::arm_set_tls(data) } -/// `prctl(PR_SET_FS, data)`—Set the x86_64 `fs` register. +/// `prctl(PR_SET_FS, data)`—Set the x86-64 `fs` register. /// /// # Safety /// @@ -101,7 +101,7 @@ pub unsafe fn set_fs(data: *mut c_void) { backend::runtime::syscalls::tls::set_fs(data) } -/// Set the x86_64 thread ID address. +/// Set the x86-64 thread ID address. /// /// # Safety /// @@ -188,7 +188,7 @@ pub const EXIT_FAILURE: i32 = backend::c::EXIT_FAILURE; /// Return fields from the main executable segment headers ("phdrs") relevant /// to initializing TLS provided to the program at startup. /// -/// `addr` will always be non-null, even when the TLS data is absent, ao that +/// `addr` will always be non-null, even when the TLS data is absent, so that /// the `addr` and `file_size` parameters are suitable for creating a slice /// with `slice::from_raw_parts`. #[inline] @@ -485,3 +485,41 @@ pub unsafe fn sigwaitinfo(set: &Sigset) -> io::Result<Siginfo> { pub unsafe fn sigtimedwait(set: &Sigset, timeout: Option<Timespec>) -> io::Result<Siginfo> { backend::runtime::syscalls::sigtimedwait(set, timeout) } + +/// `getauxval(AT_SECURE)`—Returns the Linux “secure execution” mode. +/// +/// Return a boolean value indicating whether “secure execution” mode was +/// requested, due to the process having elevated privileges. This includes +/// whether the `AT_SECURE` AUX value is set, and whether the initial real UID +/// and GID differ from the initial effective UID and GID. +/// +/// The meaning of “secure execution” mode is beyond the scope of this comment. +/// +/// # References +/// - [Linux] +/// +/// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html +#[cfg(any( + linux_raw, + any( + all(target_os = "android", target_pointer_width = "64"), + target_os = "linux", + ) +))] +#[inline] +pub fn linux_secure() -> bool { + backend::param::auxv::linux_secure() +} + +/// `brk(addr)`—Change the location of the “program break”. +/// +/// # Safety +/// +/// This is not identical to `brk` in libc. libc `brk` may have bookkeeping +/// that needs to be kept up to date that this doesn't keep up to date, so +/// don't use it unless you are implementing libc. +#[cfg(linux_raw)] +#[inline] +pub unsafe fn brk(addr: *mut c_void) -> io::Result<*mut c_void> { + backend::runtime::syscalls::brk(addr) +} diff --git a/vendor/rustix/src/shm.rs b/vendor/rustix/src/shm.rs new file mode 100644 index 000000000..450b6fcc6 --- /dev/null +++ b/vendor/rustix/src/shm.rs @@ -0,0 +1,40 @@ +//! POSIX shared memory + +use crate::fd::OwnedFd; +use crate::{backend, io, path}; + +pub use crate::backend::fs::types::Mode; +pub use crate::backend::shm::types::ShmOFlags; + +/// `shm_open(name, oflags, mode)`—Opens a shared memory object. +/// +/// For portability, `name` should begin with a slash, contain no other +/// slashes, and be no longer than an implementation-defined limit (255 on +/// Linux). +/// +/// Exactly one of [`ShmOFlags::RDONLY`] and [`ShmOFlags::RDWR`] should be +/// passed. The file descriptor will be opened with `FD_CLOEXEC` set. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/shm_open.html +/// [Linux]: https://man7.org/linux/man-pages/man3/shm_open.3.html +#[inline] +pub fn shm_open<P: path::Arg>(name: P, flags: ShmOFlags, mode: Mode) -> io::Result<OwnedFd> { + name.into_with_c_str(|name| backend::shm::syscalls::shm_open(name, flags, mode)) +} + +/// `shm_unlink(name)`—Unlinks a shared memory object. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/shm_unlink.html +/// [Linux]: https://man7.org/linux/man-pages/man3/shm_unlink.3.html +#[inline] +pub fn shm_unlink<P: path::Arg>(name: P) -> io::Result<()> { + name.into_with_c_str(backend::shm::syscalls::shm_unlink) +} diff --git a/vendor/rustix/src/signal.rs b/vendor/rustix/src/signal.rs index 43236f335..e55126f37 100644 --- a/vendor/rustix/src/signal.rs +++ b/vendor/rustix/src/signal.rs @@ -30,10 +30,12 @@ pub enum Signal { /// `SIGKILL` Kill = c::SIGKILL, /// `SIGUSR1` + #[cfg(not(target_os = "vita"))] Usr1 = c::SIGUSR1, /// `SIGSEGV` Segv = c::SIGSEGV, /// `SIGUSR2` + #[cfg(not(target_os = "vita"))] Usr2 = c::SIGUSR2, /// `SIGPIPE` Pipe = c::SIGPIPE, @@ -49,6 +51,7 @@ pub enum Signal { target_os = "aix", target_os = "haiku", target_os = "nto", + target_os = "vita", all( linux_kernel, any( @@ -63,37 +66,49 @@ pub enum Signal { )))] Stkflt = c::SIGSTKFLT, /// `SIGCHLD` + #[cfg(not(target_os = "vita"))] #[doc(alias = "Chld")] Child = c::SIGCHLD, /// `SIGCONT` + #[cfg(not(target_os = "vita"))] Cont = c::SIGCONT, /// `SIGSTOP` + #[cfg(not(target_os = "vita"))] Stop = c::SIGSTOP, /// `SIGTSTP` + #[cfg(not(target_os = "vita"))] Tstp = c::SIGTSTP, /// `SIGTTIN` + #[cfg(not(target_os = "vita"))] Ttin = c::SIGTTIN, /// `SIGTTOU` + #[cfg(not(target_os = "vita"))] Ttou = c::SIGTTOU, /// `SIGURG` + #[cfg(not(target_os = "vita"))] Urg = c::SIGURG, /// `SIGXCPU` + #[cfg(not(target_os = "vita"))] Xcpu = c::SIGXCPU, /// `SIGXFSZ` + #[cfg(not(target_os = "vita"))] Xfsz = c::SIGXFSZ, /// `SIGVTALRM` + #[cfg(not(target_os = "vita"))] #[doc(alias = "Vtalrm")] Vtalarm = c::SIGVTALRM, /// `SIGPROF` + #[cfg(not(target_os = "vita"))] Prof = c::SIGPROF, /// `SIGWINCH` + #[cfg(not(target_os = "vita"))] Winch = c::SIGWINCH, /// `SIGIO`, aka `SIGPOLL` #[doc(alias = "Poll")] - #[cfg(not(target_os = "haiku"))] + #[cfg(not(any(target_os = "haiku", target_os = "vita")))] Io = c::SIGIO, /// `SIGPWR` - #[cfg(not(any(bsd, target_os = "haiku")))] + #[cfg(not(any(bsd, target_os = "haiku", target_os = "vita")))] #[doc(alias = "Pwr")] Power = c::SIGPWR, /// `SIGSYS`, aka `SIGUNUSED` @@ -143,8 +158,10 @@ impl Signal { c::SIGBUS => Some(Self::Bus), c::SIGFPE => Some(Self::Fpe), c::SIGKILL => Some(Self::Kill), + #[cfg(not(target_os = "vita"))] c::SIGUSR1 => Some(Self::Usr1), c::SIGSEGV => Some(Self::Segv), + #[cfg(not(target_os = "vita"))] c::SIGUSR2 => Some(Self::Usr2), c::SIGPIPE => Some(Self::Pipe), c::SIGALRM => Some(Self::Alarm), @@ -155,6 +172,7 @@ impl Signal { target_os = "aix", target_os = "haiku", target_os = "nto", + target_os = "vita", all( linux_kernel, any( @@ -168,21 +186,33 @@ impl Signal { ) )))] c::SIGSTKFLT => Some(Self::Stkflt), + #[cfg(not(target_os = "vita"))] c::SIGCHLD => Some(Self::Child), + #[cfg(not(target_os = "vita"))] c::SIGCONT => Some(Self::Cont), + #[cfg(not(target_os = "vita"))] c::SIGSTOP => Some(Self::Stop), + #[cfg(not(target_os = "vita"))] c::SIGTSTP => Some(Self::Tstp), + #[cfg(not(target_os = "vita"))] c::SIGTTIN => Some(Self::Ttin), + #[cfg(not(target_os = "vita"))] c::SIGTTOU => Some(Self::Ttou), + #[cfg(not(target_os = "vita"))] c::SIGURG => Some(Self::Urg), + #[cfg(not(target_os = "vita"))] c::SIGXCPU => Some(Self::Xcpu), + #[cfg(not(target_os = "vita"))] c::SIGXFSZ => Some(Self::Xfsz), + #[cfg(not(target_os = "vita"))] c::SIGVTALRM => Some(Self::Vtalarm), + #[cfg(not(target_os = "vita"))] c::SIGPROF => Some(Self::Prof), + #[cfg(not(target_os = "vita"))] c::SIGWINCH => Some(Self::Winch), - #[cfg(not(target_os = "haiku"))] + #[cfg(not(any(target_os = "haiku", target_os = "vita")))] c::SIGIO => Some(Self::Io), - #[cfg(not(any(bsd, target_os = "haiku")))] + #[cfg(not(any(bsd, target_os = "haiku", target_os = "vita")))] c::SIGPWR => Some(Self::Power), c::SIGSYS => Some(Self::Sys), #[cfg(any( diff --git a/vendor/rustix/src/static_assertions.rs b/vendor/rustix/src/static_assertions.rs index 81824cb1c..3d0711811 100644 --- a/vendor/rustix/src/static_assertions.rs +++ b/vendor/rustix/src/static_assertions.rs @@ -1,8 +1,7 @@ //! Workarounds for Rust 1.63 where some things in the `static_assertions` -//! crate do things that don't work in const contexts. We want to call them -//! in const contexts in Rust versions where that's supported so that -//! problems are caught at compile time, and fall back to dynamic asserts -//! in Rust 1.63. +//! crate do things that don't work in const contexts. We want to call them in +//! const contexts in Rust versions where that's supported so that problems are +//! caught at compile time, and fall back to dynamic asserts in Rust 1.63. #![allow(unused_macros)] diff --git a/vendor/rustix/src/system.rs b/vendor/rustix/src/system.rs index 1f7f39ce4..cebf29e49 100644 --- a/vendor/rustix/src/system.rs +++ b/vendor/rustix/src/system.rs @@ -7,8 +7,10 @@ #![allow(unsafe_code)] use crate::backend; +#[cfg(target_os = "linux")] +use crate::backend::c; use crate::ffi::CStr; -#[cfg(not(any(target_os = "espidf", target_os = "emscripten")))] +#[cfg(not(any(target_os = "espidf", target_os = "emscripten", target_os = "vita")))] use crate::io; use core::fmt; @@ -18,6 +20,8 @@ pub use backend::system::types::Sysinfo; /// `uname()`—Returns high-level information about the runtime OS and /// hardware. /// +/// For `gethostname()`, use [`Uname::nodename`] on the result. +/// /// # References /// - [POSIX] /// - [Linux] @@ -38,6 +42,7 @@ pub use backend::system::types::Sysinfo; /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=uname§ion=3 /// [illumos]: https://illumos.org/man/2/uname /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Platform-Type.html +#[doc(alias = "gethostname")] #[inline] pub fn uname() -> Uname { Uname(backend::system::syscalls::uname()) @@ -59,6 +64,8 @@ impl Uname { /// This is intended to be a network name, however it's unable to convey /// information about hosts that have multiple names, or any information /// about where the names are visible. + /// + /// This corresponds to the `gethostname` value. #[inline] pub fn nodename(&self) -> &CStr { Self::to_cstr(self.0.nodename.as_ptr().cast()) @@ -148,9 +155,66 @@ pub fn sysinfo() -> Sysinfo { target_os = "emscripten", target_os = "espidf", target_os = "redox", + target_os = "vita", target_os = "wasi" )))] #[inline] pub fn sethostname(name: &[u8]) -> io::Result<()> { backend::system::syscalls::sethostname(name) } + +/// Reboot command for use with [`reboot`]. +#[cfg(target_os = "linux")] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(i32)] +#[non_exhaustive] +pub enum RebootCommand { + /// Disables the Ctrl-Alt-Del keystroke. + /// + /// When disabled, the keystroke will send a [`Signal::Int`] to pid 1. + /// + /// [`Signal::Int`]: crate::process::Signal::Int + CadOff = c::LINUX_REBOOT_CMD_CAD_OFF, + /// Enables the Ctrl-Alt-Del keystroke. + /// + /// When enabled, the keystroke will trigger a [`Restart`]. + /// + /// [`Restart`]: Self::Restart + CadOn = c::LINUX_REBOOT_CMD_CAD_ON, + /// Prints the message "System halted" and halts the system + Halt = c::LINUX_REBOOT_CMD_HALT, + /// Execute a kernel that has been loaded earlier with [`kexec_load`]. + /// + /// [`kexec_load`]: https://man7.org/linux/man-pages/man2/kexec_load.2.html + Kexec = c::LINUX_REBOOT_CMD_KEXEC, + /// Prints the message "Power down.", stops the system, and tries to remove + /// all power + PowerOff = c::LINUX_REBOOT_CMD_POWER_OFF, + /// Prints the message "Restarting system." and triggers a restart + Restart = c::LINUX_REBOOT_CMD_RESTART, + /// Hibernate the system by suspending to disk + SwSuspend = c::LINUX_REBOOT_CMD_SW_SUSPEND, +} + +/// `reboot`—Reboot the system or enable/disable Ctrl-Alt-Del +/// +/// The reboot syscall, despite the name, can actually do much more than +/// reboot. +/// +/// Among other things, it can: +/// - Restart, Halt, Power Off, and Suspend the system +/// - Enable and disable the Ctrl-Alt-Del keystroke +/// - Execute other kernels +/// - Terminate init inside PID namespaces +/// +/// It is highly recommended to carefully read the kernel documentation before +/// calling this function. +/// +/// # References +/// - [Linux] +/// +/// [Linux]: https://man7.org/linux/man-pages/man2/reboot.2.html +#[cfg(target_os = "linux")] +pub fn reboot(cmd: RebootCommand) -> io::Result<()> { + backend::system::syscalls::reboot(cmd) +} diff --git a/vendor/rustix/src/termios/tty.rs b/vendor/rustix/src/termios/tty.rs index 56aab9fcf..b14e602cd 100644 --- a/vendor/rustix/src/termios/tty.rs +++ b/vendor/rustix/src/termios/tty.rs @@ -51,23 +51,26 @@ fn _ttyname(dirfd: BorrowedFd<'_>, mut buffer: Vec<u8>) -> io::Result<CString> { loop { match backend::termios::syscalls::ttyname(dirfd, buffer.spare_capacity_mut()) { Err(io::Errno::RANGE) => { - buffer.reserve(buffer.capacity() + 1); // use `Vec` reallocation strategy to grow capacity exponentially + // Use `Vec` reallocation strategy to grow capacity + // exponentially. + buffer.reserve(buffer.capacity() + 1); } Ok(len) => { - // SAFETY: assume the backend returns the length of the string excluding the - // NUL. + // SAFETY: Assume the backend returns the length of the string + // excluding the NUL. unsafe { buffer.set_len(len + 1); } // SAFETY: - // - "ttyname_r stores this pathname in the buffer buf" - // - [POSIX definition 3.271: Pathname]: "A string that is used to identify a - // file." - // - [POSIX definition 3.375: String]: "A contiguous sequence of bytes - // terminated by and including the first null byte." + // - “ttyname_r stores this pathname in the buffer buf” + // - [POSIX definition 3.271: Pathname]: “A string that is used + // to identify a file.” + // - [POSIX definition 3.375: String]: “A contiguous sequence + // of bytes terminated by and including the first null byte.” // - // Thus, there will be a single NUL byte at the end of the string. + // Thus, there will be a single NUL byte at the end of the + // string. // // [POSIX definition 3.271: Pathname]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_271 // [POSIX definition 3.375: String]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_375 diff --git a/vendor/rustix/src/termios/types.rs b/vendor/rustix/src/termios/types.rs index 0c44ed2e8..720352442 100644 --- a/vendor/rustix/src/termios/types.rs +++ b/vendor/rustix/src/termios/types.rs @@ -289,11 +289,12 @@ bitflags! { target_os = "aix", target_os = "emscripten", target_os = "haiku", + target_os = "hurd", target_os = "redox", )))] const IUTF8 = c::IUTF8; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -508,7 +509,7 @@ bitflags! { )))] const VT1 = c::VT1; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -566,12 +567,13 @@ bitflags! { target_os = "aix", target_os = "emscripten", target_os = "haiku", + target_os = "hurd", target_os = "nto", target_os = "redox", )))] const CMSPAR = c::CMSPAR; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -637,7 +639,7 @@ bitflags! { /// `IEXTEN` const IEXTEN = c::IEXTEN; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -806,7 +808,18 @@ pub mod speed { /// Translate from a `c::speed_t` code to an arbitrary integer speed value /// `u32`. - #[cfg(not(any(linux_kernel, bsd)))] + /// + /// On BSD platforms, integer speed values are already the same as their + /// encoded values, and on Linux platforms, we use `TCGETS2`/`TCSETS2` + /// and the `c_ispeed`/`c_ospeed`` fields, except that on Linux on + /// PowerPC on QEMU, `TCGETS2`/`TCSETS2` don't set `c_ispeed`/`c_ospeed`. + #[cfg(not(any( + bsd, + all( + linux_kernel, + not(any(target_arch = "powerpc", target_arch = "powerpc64")) + ) + )))] pub(crate) const fn decode(encoded_speed: c::speed_t) -> Option<u32> { match encoded_speed { c::B0 => Some(0), @@ -1131,6 +1144,7 @@ impl SpecialCodeIndex { solarish, target_os = "aix", target_os = "haiku", + target_os = "hurd", target_os = "nto", )))] pub const VSWTC: Self = Self(c::VSWTC as usize); @@ -1263,8 +1277,8 @@ fn termios_layouts() { check_renamed_struct_renamed_field!(Termios, termios, local_modes, c_lflag); check_renamed_struct_renamed_field!(Termios, termios, special_codes, c_cc); - // On everything except PowerPC, `termios` matches `termios2` except for - // the addition of `c_ispeed` and `c_ospeed`. + // On everything except PowerPC, `termios` matches `termios2` except + // for the addition of `c_ispeed` and `c_ospeed`. #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] const_assert_eq!( memoffset::offset_of!(Termios, input_speed), diff --git a/vendor/rustix/src/thread/clock.rs b/vendor/rustix/src/thread/clock.rs index 8060c0238..986e1f9a3 100644 --- a/vendor/rustix/src/thread/clock.rs +++ b/vendor/rustix/src/thread/clock.rs @@ -9,6 +9,7 @@ pub use crate::timespec::Timespec; target_os = "freebsd", // FreeBSD 12 has clock_nanosleep, but libc targets FreeBSD 11. target_os = "openbsd", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] pub use crate::clockid::ClockId; @@ -34,6 +35,7 @@ pub use crate::clockid::ClockId; target_os = "haiku", target_os = "openbsd", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] #[inline] @@ -62,6 +64,7 @@ pub fn clock_nanosleep_relative(id: ClockId, request: &Timespec) -> NanosleepRel target_os = "haiku", target_os = "openbsd", target_os = "redox", + target_os = "vita", target_os = "wasi", )))] #[inline] diff --git a/vendor/rustix/src/thread/libcap.rs b/vendor/rustix/src/thread/libcap.rs index 19f81a904..0a0fbb4ca 100644 --- a/vendor/rustix/src/thread/libcap.rs +++ b/vendor/rustix/src/thread/libcap.rs @@ -103,7 +103,7 @@ bitflags! { /// `CAP_CHECKPOINT_RESTORE` const CHECKPOINT_RESTORE = 1 << linux_raw_sys::general::CAP_CHECKPOINT_RESTORE; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/thread/prctl.rs b/vendor/rustix/src/thread/prctl.rs index b2d40d65c..999764cb1 100644 --- a/vendor/rustix/src/thread/prctl.rs +++ b/vendor/rustix/src/thread/prctl.rs @@ -205,8 +205,8 @@ pub enum Capability { /// cleared on successful return from `chown` (not implemented). FileSetID = linux_raw_sys::general::CAP_FSETID, /// Overrides the restriction that the real or effective user ID of a - /// process sending a signal must match the real or effective user ID - /// of the process receiving the signal. + /// process sending a signal must match the real or effective user ID of + /// the process receiving the signal. Kill = linux_raw_sys::general::CAP_KILL, /// Allows `setgid` manipulation. Allows `setgroups`. Allows forged gids on /// socket credentials passing. @@ -366,8 +366,9 @@ pub enum Capability { /// /// [`Capability::SystemAdmin`] is required to use bpf_probe_write_user. /// - /// [`Capability::SystemAdmin`] is required to iterate system wide loaded - /// programs, maps, links, BTFs and convert their IDs to file descriptors. + /// [`Capability::SystemAdmin`] is required to iterate system-wide loaded + /// programs, maps, links, and BTFs, and convert their IDs to file + /// descriptors. /// /// [`Capability::PerformanceMonitoring`] and /// [`Capability::BerkeleyPacketFilters`] are required to load tracing @@ -443,7 +444,7 @@ bitflags! { /// Set [`NO_CAP_AMBIENT_RAISE`] irreversibly. const NO_CAP_AMBIENT_RAISE_LOCKED = 1_u32 << 7; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -742,18 +743,20 @@ const PR_MTE_TAG_SHIFT: u32 = 3; const PR_MTE_TAG_MASK: u32 = 0xffff_u32 << PR_MTE_TAG_SHIFT; bitflags! { - /// Zero means addresses that are passed for the purpose of being dereferenced by the kernel must be untagged. + /// Zero means addresses that are passed for the purpose of being + /// dereferenced by the kernel must be untagged. #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct TaggedAddressMode: u32 { - /// Addresses that are passed for the purpose of being dereferenced by the kernel may be tagged. + /// Addresses that are passed for the purpose of being dereferenced by + /// the kernel may be tagged. const ENABLED = 1_u32 << 0; /// Synchronous tag check fault mode. const TCF_SYNC = 1_u32 << 1; /// Asynchronous tag check fault mode. const TCF_ASYNC = 1_u32 << 2; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -781,8 +784,8 @@ const PR_SET_TAGGED_ADDR_CTRL: c_int = 55; /// /// # Safety /// -/// Please ensure the conditions necessary to safely call this function, -/// as detailed in the references above. +/// Please ensure the conditions necessary to safely call this function, as +/// detailed in the references above. /// /// [`prctl(PR_SET_TAGGED_ADDR_CTRL,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] @@ -810,8 +813,8 @@ const PR_SYS_DISPATCH_OFF: usize = 0; /// /// # Safety /// -/// Please ensure the conditions necessary to safely call this function, -/// as detailed in the references above. +/// Please ensure the conditions necessary to safely call this function, as +/// detailed in the references above. /// /// [`prctl(PR_SET_SYSCALL_USER_DISPATCH,PR_SYS_DISPATCH_OFF,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] @@ -856,8 +859,8 @@ impl TryFrom<u8> for SysCallUserDispatchFastSwitch { /// /// # Safety /// -/// Please ensure the conditions necessary to safely call this function, -/// as detailed in the references above. +/// Please ensure the conditions necessary to safely call this function, as +/// detailed in the references above. /// /// [`prctl(PR_SET_SYSCALL_USER_DISPATCH,PR_SYS_DISPATCH_ON,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] diff --git a/vendor/rustix/src/thread/setns.rs b/vendor/rustix/src/thread/setns.rs index 4568912b2..ef61d11e8 100644 --- a/vendor/rustix/src/thread/setns.rs +++ b/vendor/rustix/src/thread/setns.rs @@ -31,7 +31,7 @@ bitflags! { /// Network name space. const NETWORK = CLONE_NEWNET; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } @@ -86,7 +86,7 @@ bitflags! { /// `CLONE_SYSVSEM`. const SYSVSEM = CLONE_SYSVSEM; - /// <https://docs.rs/bitflags/latest/bitflags/#externally-defined-flags> + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> const _ = !0; } } diff --git a/vendor/rustix/src/timespec.rs b/vendor/rustix/src/timespec.rs index 51c2d2443..a2df0e7b9 100644 --- a/vendor/rustix/src/timespec.rs +++ b/vendor/rustix/src/timespec.rs @@ -1,6 +1,7 @@ //! `Timespec` and related types, which are used by multiple public API //! modules. +#[cfg(not(fix_y2038))] use crate::backend::c; /// `struct timespec` @@ -28,18 +29,22 @@ pub type Secs = c::time_t; #[cfg(fix_y2038)] pub type Secs = i64; -/// A type for the `tv_nsec` field of [`Timespec`]. -#[cfg(all(libc, target_arch = "x86_64", target_pointer_width = "32"))] +/// A type for the `tv_sec` field of [`Timespec`]. +#[cfg(any( + fix_y2038, + linux_raw, + all(libc, target_arch = "x86_64", target_pointer_width = "32") +))] pub type Nsecs = i64; /// A type for the `tv_nsec` field of [`Timespec`]. -#[cfg(all(libc, not(all(target_arch = "x86_64", target_pointer_width = "32"))))] +#[cfg(all( + not(fix_y2038), + libc, + not(all(target_arch = "x86_64", target_pointer_width = "32")) +))] pub type Nsecs = c::c_long; -/// A type for the `tv_nsec` field of [`Timespec`]. -#[cfg(linux_raw)] -pub type Nsecs = i64; - /// 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. @@ -52,7 +57,7 @@ pub(crate) struct LibcTimespec { #[cfg(target_endian = "big")] padding: core::mem::MaybeUninit<u32>, - pub(crate) tv_nsec: Nsecs, + pub(crate) tv_nsec: i32, #[cfg(target_endian = "little")] padding: core::mem::MaybeUninit<u32>, @@ -64,7 +69,7 @@ impl From<LibcTimespec> for Timespec { fn from(t: LibcTimespec) -> Self { Self { tv_sec: t.tv_sec, - tv_nsec: t.tv_nsec, + tv_nsec: t.tv_nsec as _, } } } @@ -75,7 +80,7 @@ impl From<Timespec> for LibcTimespec { fn from(t: Timespec) -> Self { Self { tv_sec: t.tv_sec, - tv_nsec: t.tv_nsec, + tv_nsec: t.tv_nsec as _, padding: core::mem::MaybeUninit::uninit(), } } |