diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
commit | 9918693037dce8aa4bb6f08741b6812923486c18 (patch) | |
tree | 21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /vendor/rustix/src/backend | |
parent | Releasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff) | |
download | rustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip |
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/rustix/src/backend')
42 files changed, 567 insertions, 136 deletions
diff --git a/vendor/rustix/src/backend/libc/c.rs b/vendor/rustix/src/backend/libc/c.rs index f788cb120..d3a1e5f4a 100644 --- a/vendor/rustix/src/backend/libc/c.rs +++ b/vendor/rustix/src/backend/libc/c.rs @@ -130,8 +130,8 @@ pub(super) use libc::{ blksize64_t as blksize_t, fstat64 as fstat, fstatfs64 as fstatfs, fstatvfs64 as fstatvfs, ftruncate64 as ftruncate, getrlimit64 as getrlimit, ino_t, lseek64 as lseek, mmap, off64_t as off_t, openat, posix_fadvise64 as posix_fadvise, preadv, pwritev, - rlimit64 as rlimit, setrlimit64 as setrlimit, statfs64 as statfs, statvfs64 as statvfs, - RLIM_INFINITY, + rlimit64 as rlimit, setrlimit64 as setrlimit, stat64at as fstatat, statfs64 as statfs, + statvfs64 as statvfs, RLIM_INFINITY, }; #[cfg(any(linux_like, target_os = "hurd"))] pub(super) use libc::{ diff --git a/vendor/rustix/src/backend/libc/event/epoll.rs b/vendor/rustix/src/backend/libc/event/epoll.rs index b41b05711..ced3be103 100644 --- a/vendor/rustix/src/backend/libc/event/epoll.rs +++ b/vendor/rustix/src/backend/libc/event/epoll.rs @@ -278,8 +278,8 @@ pub fn wait(epoll: impl AsFd, event_list: &mut EventVec, timeout: c::c_int) -> i /// An iterator over the `Event`s in an `EventVec`. pub struct Iter<'a> { /// Use `Copied` to copy the struct, since `Event` is `packed` on some - /// platforms, and it's common for users to directly destructure it, - /// which would lead to errors about forming references to packed fields. + /// platforms, and it's common for users to directly destructure it, which + /// would lead to errors about forming references to packed fields. iter: core::iter::Copied<slice::Iter<'a, Event>>, } diff --git a/vendor/rustix/src/backend/libc/event/poll_fd.rs b/vendor/rustix/src/backend/libc/event/poll_fd.rs index 42f94f3c7..32fd83dd0 100644 --- a/vendor/rustix/src/backend/libc/event/poll_fd.rs +++ b/vendor/rustix/src/backend/libc/event/poll_fd.rs @@ -12,7 +12,7 @@ use { bitflags! { /// `POLL*` flags for use with [`poll`]. /// - /// [`poll`]: crate::io::poll + /// [`poll`]: crate::event::poll #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct PollFlags: c::c_short { diff --git a/vendor/rustix/src/backend/libc/event/syscalls.rs b/vendor/rustix/src/backend/libc/event/syscalls.rs index f2dcdf5ad..725ec8250 100644 --- a/vendor/rustix/src/backend/libc/event/syscalls.rs +++ b/vendor/rustix/src/backend/libc/event/syscalls.rs @@ -181,3 +181,11 @@ pub(crate) fn port_send( ) -> io::Result<()> { unsafe { ret(c::port_send(borrowed_fd(port), events, userdata)) } } + +#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] +pub(crate) fn pause() { + let r = unsafe { libc::pause() }; + let errno = libc_errno::errno().0; + debug_assert_eq!(r, -1); + debug_assert_eq!(errno, libc::EINTR); +} diff --git a/vendor/rustix/src/backend/libc/event/types.rs b/vendor/rustix/src/backend/libc/event/types.rs index ea4776667..a04d7e6cf 100644 --- a/vendor/rustix/src/backend/libc/event/types.rs +++ b/vendor/rustix/src/backend/libc/event/types.rs @@ -17,7 +17,7 @@ use bitflags::bitflags; bitflags! { /// `EFD_*` flags for use with [`eventfd`]. /// - /// [`eventfd`]: crate::io::eventfd + /// [`eventfd`]: crate::event::eventfd #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct EventfdFlags: u32 { diff --git a/vendor/rustix/src/backend/libc/fs/dir.rs b/vendor/rustix/src/backend/libc/fs/dir.rs index 0df1ea1b5..82a0a908f 100644 --- a/vendor/rustix/src/backend/libc/fs/dir.rs +++ b/vendor/rustix/src/backend/libc/fs/dir.rs @@ -2,7 +2,7 @@ use super::types::FileType; use crate::backend::c; use crate::backend::conv::owned_fd; -use crate::fd::{AsFd, BorrowedFd}; +use crate::fd::{AsFd, BorrowedFd, OwnedFd}; use crate::ffi::{CStr, CString}; use crate::fs::{fcntl_getfl, openat, Mode, OFlags}; #[cfg(not(target_os = "vita"))] @@ -48,8 +48,34 @@ pub struct Dir { } impl Dir { - /// Construct a `Dir` that reads entries from the given directory - /// file descriptor. + /// Take ownership of `fd` and construct a `Dir` that reads entries from + /// the given directory file descriptor. + #[inline] + pub fn new<Fd: Into<OwnedFd>>(fd: Fd) -> io::Result<Self> { + Self::_new(fd.into()) + } + + #[inline] + fn _new(fd: OwnedFd) -> io::Result<Self> { + let raw = owned_fd(fd); + unsafe { + let libc_dir = c::fdopendir(raw); + + if let Some(libc_dir) = NonNull::new(libc_dir) { + Ok(Self { + libc_dir, + any_errors: false, + }) + } else { + let err = io::Errno::last_os_error(); + let _ = c::close(raw); + Err(err) + } + } + } + + /// Borrow `fd` and construct a `Dir` that reads entries from the given + /// directory file descriptor. #[inline] pub fn read_from<Fd: AsFd>(fd: Fd) -> io::Result<Self> { Self::_read_from(fd.as_fd()) @@ -393,5 +419,5 @@ fn dir_iterator_handles_io_errors() { } assert!(matches!(dir.next(), Some(Err(_)))); - assert!(matches!(dir.next(), None)); + assert!(dir.next().is_none()); } diff --git a/vendor/rustix/src/backend/libc/fs/syscalls.rs b/vendor/rustix/src/backend/libc/fs/syscalls.rs index 5e0b62f8e..fcf069a83 100644 --- a/vendor/rustix/src/backend/libc/fs/syscalls.rs +++ b/vendor/rustix/src/backend/libc/fs/syscalls.rs @@ -2,8 +2,7 @@ use crate::backend::c; #[cfg(any( - apple, - linux_kernel, + not(target_os = "redox"), feature = "alloc", all(linux_kernel, feature = "procfs") ))] @@ -275,10 +274,7 @@ pub(crate) fn readlink(path: &CStr, buf: &mut [u8]) -> io::Result<usize> { } } -#[cfg(all( - any(feature = "alloc", all(linux_kernel, feature = "procfs")), - not(target_os = "redox") -))] +#[cfg(not(target_os = "redox"))] #[inline] pub(crate) fn readlinkat( dirfd: BorrowedFd<'_>, @@ -660,7 +656,7 @@ pub(crate) fn lstat(path: &CStr) -> io::Result<Stat> { } } -#[cfg(not(any(target_os = "aix", target_os = "espidf", target_os = "redox")))] +#[cfg(not(any(target_os = "espidf", target_os = "redox")))] pub(crate) fn statat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<Stat> { // See the comments in `fstat` about using `crate::fs::statx` here. #[cfg(all( @@ -1703,7 +1699,7 @@ pub(crate) fn ftruncate(fd: BorrowedFd<'_>, length: u64) -> io::Result<()> { } #[cfg(any(linux_kernel, target_os = "freebsd"))] -pub(crate) fn memfd_create(path: &CStr, flags: MemfdFlags) -> io::Result<OwnedFd> { +pub(crate) fn memfd_create(name: &CStr, flags: MemfdFlags) -> io::Result<OwnedFd> { #[cfg(target_os = "freebsd")] weakcall! { fn memfd_create( @@ -1720,7 +1716,7 @@ pub(crate) fn memfd_create(path: &CStr, flags: MemfdFlags) -> io::Result<OwnedFd ) via SYS_memfd_create -> c::c_int } - unsafe { ret_owned_fd(memfd_create(c_str(path), bitflags_bits!(flags))) } + unsafe { ret_owned_fd(memfd_create(c_str(name), bitflags_bits!(flags))) } } #[cfg(linux_kernel)] diff --git a/vendor/rustix/src/backend/libc/mm/types.rs b/vendor/rustix/src/backend/libc/mm/types.rs index ef335d27a..a4aa3e232 100644 --- a/vendor/rustix/src/backend/libc/mm/types.rs +++ b/vendor/rustix/src/backend/libc/mm/types.rs @@ -6,7 +6,7 @@ bitflags! { /// /// For `PROT_NONE`, use `ProtFlags::empty()`. /// - /// [`mmap`]: crate::io::mmap + /// [`mmap`]: crate::mm::mmap #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct ProtFlags: u32 { @@ -27,7 +27,7 @@ bitflags! { /// /// For `PROT_NONE`, use `MprotectFlags::empty()`. /// - /// [`mprotect`]: crate::io::mprotect + /// [`mprotect`]: crate::mm::mprotect #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MprotectFlags: u32 { @@ -69,8 +69,8 @@ bitflags! { /// /// For `MAP_ANONYMOUS` (aka `MAP_ANON`), see [`mmap_anonymous`]. /// - /// [`mmap`]: crate::io::mmap - /// [`mmap_anonymous`]: crates::io::mmap_anonymous + /// [`mmap`]: crate::mm::mmap + /// [`mmap_anonymous`]: crates::mm::mmap_anonymous #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MapFlags: u32 { @@ -242,8 +242,8 @@ bitflags! { /// /// For `MREMAP_FIXED`, see [`mremap_fixed`]. /// - /// [`mremap`]: crate::io::mremap - /// [`mremap_fixed`]: crate::io::mremap_fixed + /// [`mremap`]: crate::mm::mremap + /// [`mremap_fixed`]: crate::mm::mremap_fixed #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MremapFlags: u32 { @@ -258,7 +258,7 @@ bitflags! { bitflags! { /// `MS_*` flags for use with [`msync`]. /// - /// [`msync`]: crate::io::msync + /// [`msync`]: crate::mm::msync #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MsyncFlags: u32 { @@ -281,7 +281,7 @@ bitflags! { bitflags! { /// `MLOCK_*` flags for use with [`mlock_with`]. /// - /// [`mlock_with`]: crate::io::mlock_with + /// [`mlock_with`]: crate::mm::mlock_with #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MlockFlags: u32 { @@ -383,10 +383,10 @@ pub enum Advice { /// `MADV_UNMERGEABLE` #[cfg(linux_kernel)] LinuxUnmergeable = bitcast!(c::MADV_UNMERGEABLE), - /// `MADV_HUGEPAGE` (since Linux 2.6.38) + /// `MADV_HUGEPAGE` #[cfg(linux_kernel)] LinuxHugepage = bitcast!(c::MADV_HUGEPAGE), - /// `MADV_NOHUGEPAGE` (since Linux 2.6.38) + /// `MADV_NOHUGEPAGE` #[cfg(linux_kernel)] LinuxNoHugepage = bitcast!(c::MADV_NOHUGEPAGE), /// `MADV_DONTDUMP` (since Linux 3.4) @@ -429,7 +429,7 @@ impl Advice { bitflags! { /// `O_*` flags for use with [`userfaultfd`]. /// - /// [`userfaultfd`]: crate::io::userfaultfd + /// [`userfaultfd`]: crate::mm::userfaultfd #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct UserfaultfdFlags: u32 { @@ -451,8 +451,17 @@ bitflags! { #[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; + /// Used together with `MCL_CURRENT`, `MCL_FUTURE`, or both. Mark all + /// current (with `MCL_CURRENT`) or future (with `MCL_FUTURE`) mappings + /// to lock pages when they are faulted in. When used with + /// `MCL_CURRENT`, all present pages are locked, but `mlockall` will + /// not fault in non-present pages. When used with `MCL_FUTURE`, all + /// future mappings will be marked to lock pages when they are faulted + /// in, but they will not be populated by the lock when the mapping is + /// created. `MCL_ONFAULT` must be used with either `MCL_CURRENT` or + /// `MCL_FUTURE` or both. + #[cfg(linux_kernel)] + const ONFAULT = bitcast!(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 diff --git a/vendor/rustix/src/backend/libc/mount/types.rs b/vendor/rustix/src/backend/libc/mount/types.rs index d4f9c2da7..238f2128e 100644 --- a/vendor/rustix/src/backend/libc/mount/types.rs +++ b/vendor/rustix/src/backend/libc/mount/types.rs @@ -299,9 +299,9 @@ bitflags! { #[cfg(linux_kernel)] bitflags! { - /// `MS_*` constants for use with [`change_mount`]. + /// `MS_*` constants for use with [`mount_change`]. /// - /// [`change_mount`]: crate::mount::change_mount + /// [`mount_change`]: crate::mount::mount_change #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MountPropagationFlags: c::c_ulong { diff --git a/vendor/rustix/src/backend/libc/net/syscalls.rs b/vendor/rustix/src/backend/libc/net/syscalls.rs index 97b862033..33411c01a 100644 --- a/vendor/rustix/src/backend/libc/net/syscalls.rs +++ b/vendor/rustix/src/backend/libc/net/syscalls.rs @@ -100,7 +100,7 @@ pub(crate) fn sendto_v4( send_recv_len(buf.len()), bitflags_bits!(flags), as_ptr(&encode_sockaddr_v4(addr)).cast::<c::sockaddr>(), - size_of::<SocketAddrV4>() as _, + size_of::<c::sockaddr_in>() as c::socklen_t, )) } } @@ -119,7 +119,7 @@ pub(crate) fn sendto_v6( send_recv_len(buf.len()), bitflags_bits!(flags), as_ptr(&encode_sockaddr_v6(addr)).cast::<c::sockaddr>(), - size_of::<SocketAddrV6>() as _, + size_of::<c::sockaddr_in6>() as c::socklen_t, )) } } diff --git a/vendor/rustix/src/backend/libc/pipe/types.rs b/vendor/rustix/src/backend/libc/pipe/types.rs index 1004e41f7..d5cc73962 100644 --- a/vendor/rustix/src/backend/libc/pipe/types.rs +++ b/vendor/rustix/src/backend/libc/pipe/types.rs @@ -7,7 +7,7 @@ use {crate::backend::c, bitflags::bitflags}; bitflags! { /// `O_*` constants for use with [`pipe_with`]. /// - /// [`pipe_with`]: crate::io::pipe_with + /// [`pipe_with`]: crate::pipe::pipe_with #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct PipeFlags: u32 { @@ -34,8 +34,8 @@ bitflags! { #[cfg(linux_kernel)] bitflags! { - /// `SPLICE_F_*` constants for use with [`splice`], [`vmsplice`], - /// and [`tee`]. + /// `SPLICE_F_*` constants for use with [`splice`], [`vmsplice`], and + /// [`tee`]. #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct SpliceFlags: c::c_uint { diff --git a/vendor/rustix/src/backend/libc/process/mod.rs b/vendor/rustix/src/backend/libc/process/mod.rs index b89096199..39803b521 100644 --- a/vendor/rustix/src/backend/libc/process/mod.rs +++ b/vendor/rustix/src/backend/libc/process/mod.rs @@ -1,4 +1,4 @@ -#[cfg(any(linux_kernel, target_os = "dragonfly", target_os = "fuchsia"))] +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] pub(crate) mod cpu_set; #[cfg(not(windows))] pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/libc/process/syscalls.rs b/vendor/rustix/src/backend/libc/process/syscalls.rs index ec31e0ea7..46fd18211 100644 --- a/vendor/rustix/src/backend/libc/process/syscalls.rs +++ b/vendor/rustix/src/backend/libc/process/syscalls.rs @@ -1,6 +1,6 @@ //! libc syscalls supporting `rustix::process`. -#[cfg(any(linux_kernel, target_os = "dragonfly", target_os = "fuchsia"))] +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] use super::types::RawCpuSet; use crate::backend::c; #[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))] @@ -72,6 +72,14 @@ use { super::super::conv::ret_owned_fd, crate::process::PidfdFlags, crate::process::PidfdGetfdFlags, }; +#[cfg(any(linux_kernel, target_os = "dragonfly"))] +#[inline] +pub(crate) fn sched_getcpu() -> usize { + let r = unsafe { libc::sched_getcpu() }; + debug_assert!(r >= 0); + r as usize +} + #[cfg(feature = "fs")] #[cfg(not(target_os = "wasi"))] pub(crate) fn chdir(path: &CStr) -> io::Result<()> { @@ -181,7 +189,7 @@ pub(crate) fn getpgrp() -> Pid { } } -#[cfg(any(linux_kernel, target_os = "dragonfly", target_os = "fuchsia"))] +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] #[inline] pub(crate) fn sched_getaffinity(pid: Option<Pid>, cpuset: &mut RawCpuSet) -> io::Result<()> { unsafe { @@ -193,7 +201,7 @@ pub(crate) fn sched_getaffinity(pid: Option<Pid>, cpuset: &mut RawCpuSet) -> io: } } -#[cfg(any(linux_kernel, target_os = "dragonfly", target_os = "fuchsia"))] +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] #[inline] pub(crate) fn sched_setaffinity(pid: Option<Pid>, cpuset: &RawCpuSet) -> io::Result<()> { unsafe { diff --git a/vendor/rustix/src/backend/libc/process/types.rs b/vendor/rustix/src/backend/libc/process/types.rs index 8689c414a..f914128df 100644 --- a/vendor/rustix/src/backend/libc/process/types.rs +++ b/vendor/rustix/src/backend/libc/process/types.rs @@ -155,10 +155,12 @@ pub type RawCpuid = u32; #[cfg(freebsdlike)] pub type RawId = c::id_t; -#[cfg(any(linux_kernel, target_os = "dragonfly", target_os = "fuchsia"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] pub(crate) type RawCpuSet = c::cpu_set_t; +#[cfg(freebsdlike)] +pub(crate) type RawCpuSet = c::cpuset_t; -#[cfg(any(linux_kernel, target_os = "dragonfly", target_os = "fuchsia"))] +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] #[inline] pub(crate) fn raw_cpu_set_new() -> RawCpuSet { let mut set = unsafe { core::mem::zeroed() }; @@ -166,7 +168,5 @@ pub(crate) fn raw_cpu_set_new() -> RawCpuSet { set } -#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] pub(crate) const CPU_SETSIZE: usize = c::CPU_SETSIZE as usize; -#[cfg(target_os = "dragonfly")] -pub(crate) const CPU_SETSIZE: usize = 256; diff --git a/vendor/rustix/src/backend/libc/termios/syscalls.rs b/vendor/rustix/src/backend/libc/termios/syscalls.rs index 35d4e2349..a833aea8d 100644 --- a/vendor/rustix/src/backend/libc/termios/syscalls.rs +++ b/vendor/rustix/src/backend/libc/termios/syscalls.rs @@ -115,6 +115,15 @@ pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result<Termios> { pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result<Pid> { unsafe { let pid = ret_pid_t(c::tcgetpgrp(borrowed_fd(fd)))?; + + // This doesn't appear to be documented, but on Linux, it appears + // `tcsetpgrp` can succceed and set the pid to 0 if we pass it a + // pseudo-terminal device fd. For now, translate it into `OPNOTSUPP`. + #[cfg(linux_kernel)] + if pid == 0 { + return Err(io::Errno::OPNOTSUPP); + } + Ok(Pid::from_raw_unchecked(pid)) } } diff --git a/vendor/rustix/src/backend/libc/time/types.rs b/vendor/rustix/src/backend/libc/time/types.rs index 1514b02d0..5254c6bc7 100644 --- a/vendor/rustix/src/backend/libc/time/types.rs +++ b/vendor/rustix/src/backend/libc/time/types.rs @@ -83,9 +83,11 @@ bitflags! { #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct TimerfdFlags: u32 { /// `TFD_NONBLOCK` + #[doc(alias = "TFD_NONBLOCK")] const NONBLOCK = bitcast!(c::TFD_NONBLOCK); /// `TFD_CLOEXEC` + #[doc(alias = "TFD_CLOEXEC")] const CLOEXEC = bitcast!(c::TFD_CLOEXEC); /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> @@ -102,10 +104,12 @@ bitflags! { #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct TimerfdTimerFlags: u32 { /// `TFD_TIMER_ABSTIME` + #[doc(alias = "TFD_TIMER_ABSTIME")] const ABSTIME = bitcast!(c::TFD_TIMER_ABSTIME); /// `TFD_TIMER_CANCEL_ON_SET` #[cfg(linux_kernel)] + #[doc(alias = "TFD_TIMER_CANCEL_ON_SET")] const CANCEL_ON_SET = bitcast!(c::TFD_TIMER_CANCEL_ON_SET); /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> @@ -127,6 +131,7 @@ pub enum TimerfdClockId { /// epoch, 1970-01-01T00:00:00Z. The clock is externally settable, so it is /// not monotonic. Successive reads may see decreasing times, so it isn't /// reliable for measuring durations. + #[doc(alias = "CLOCK_REALTIME")] Realtime = bitcast!(c::CLOCK_REALTIME), /// `CLOCK_MONOTONIC`—A clock that tells an abstract time. @@ -137,12 +142,14 @@ pub enum TimerfdClockId { /// /// This clock does not advance while the system is suspended; see /// `Boottime` for a clock that does. + #[doc(alias = "CLOCK_MONOTONIC")] Monotonic = bitcast!(c::CLOCK_MONOTONIC), /// `CLOCK_BOOTTIME`—Like `Monotonic`, but advances while suspended. /// /// This clock is similar to `Monotonic`, but does advance while the system /// is suspended. + #[doc(alias = "CLOCK_BOOTTIME")] Boottime = bitcast!(c::CLOCK_BOOTTIME), /// `CLOCK_REALTIME_ALARM`—Like `Realtime`, but wakes a suspended system. @@ -150,6 +157,7 @@ pub enum TimerfdClockId { /// This clock is like `Realtime`, but can wake up a suspended system. /// /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. + #[doc(alias = "CLOCK_REALTIME_ALARM")] RealtimeAlarm = bitcast!(c::CLOCK_REALTIME_ALARM), /// `CLOCK_BOOTTIME_ALARM`—Like `Boottime`, but wakes a suspended system. @@ -157,6 +165,7 @@ pub enum TimerfdClockId { /// This clock is like `Boottime`, but can wake up a suspended system. /// /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. + #[doc(alias = "CLOCK_BOOTTIME_ALARM")] BoottimeAlarm = bitcast!(c::CLOCK_BOOTTIME_ALARM), } diff --git a/vendor/rustix/src/backend/linux_raw/arch/x86.rs b/vendor/rustix/src/backend/linux_raw/arch/x86.rs index 581cde278..e789181cc 100644 --- a/vendor/rustix/src/backend/linux_raw/arch/x86.rs +++ b/vendor/rustix/src/backend/linux_raw/arch/x86.rs @@ -148,10 +148,10 @@ pub(in crate::backend) unsafe fn indirect_syscall5( // clobbered as the return value anyway. asm!( "push esi", - "push DWORD PTR [eax + 0]", - "mov esi, DWORD PTR [eax + 4]", - "mov eax, DWORD PTR [eax + 8]", - "call DWORD PTR [esp]", + "push [eax + 0]", + "mov esi, [eax + 4]", + "mov eax, [eax + 8]", + "call [esp]", "pop esi", "pop esi", inout("eax") &[callee as _, a3.to_asm(), nr.to_asm()] => r0, @@ -186,11 +186,11 @@ pub(in crate::backend) unsafe fn indirect_syscall6( asm!( "push ebp", "push esi", - "push DWORD PTR [eax + 0]", - "mov esi, DWORD PTR [eax + 4]", - "mov ebp, DWORD PTR [eax + 8]", - "mov eax, DWORD PTR [eax + 12]", - "call DWORD PTR [esp]", + "push [eax + 0]", + "mov esi, [eax + 4]", + "mov ebp, [eax + 8]", + "mov eax, [eax + 12]", + "call [esp]", "pop esi", "pop esi", "pop ebp", @@ -441,9 +441,9 @@ pub(in crate::backend) unsafe fn syscall6( asm!( "push ebp", "push esi", - "mov esi, DWORD PTR [eax + 0]", - "mov ebp, DWORD PTR [eax + 4]", - "mov eax, DWORD PTR [eax + 8]", + "mov esi, [eax + 0]", + "mov ebp, [eax + 4]", + "mov eax, [eax + 8]", "int $$0x80", "pop esi", "pop ebp", @@ -472,9 +472,9 @@ pub(in crate::backend) unsafe fn syscall6_readonly( asm!( "push ebp", "push esi", - "mov esi, DWORD PTR [eax + 0]", - "mov ebp, DWORD PTR [eax + 4]", - "mov eax, DWORD PTR [eax + 8]", + "mov esi, [eax + 0]", + "mov ebp, [eax + 4]", + "mov eax, [eax + 8]", "int $$0x80", "pop esi", "pop ebp", diff --git a/vendor/rustix/src/backend/linux_raw/c.rs b/vendor/rustix/src/backend/linux_raw/c.rs index 01c5eafb1..edc9eb862 100644 --- a/vendor/rustix/src/backend/linux_raw/c.rs +++ b/vendor/rustix/src/backend/linux_raw/c.rs @@ -29,6 +29,7 @@ pub(crate) use linux_raw_sys::general::epoll_event; not(feature = "use-explicitly-provided-auxv"), any( feature = "param", + feature = "process", feature = "runtime", feature = "time", target_arch = "x86", @@ -142,6 +143,8 @@ pub(crate) const EXIT_SUCCESS: c_int = 0; pub(crate) const EXIT_FAILURE: c_int = 1; #[cfg(feature = "process")] pub(crate) const EXIT_SIGNALED_SIGABRT: c_int = 128 + linux_raw_sys::general::SIGABRT as c_int; +#[cfg(feature = "runtime")] +pub(crate) const CLONE_CHILD_SETTID: c_int = linux_raw_sys::general::CLONE_CHILD_SETTID as c_int; #[cfg(feature = "process")] pub(crate) use linux_raw_sys::{ @@ -266,6 +269,14 @@ pub(crate) const CLOCK_THREAD_CPUTIME_ID: c_int = linux_raw_sys::general::CLOCK_THREAD_CPUTIME_ID as _; pub(crate) const CLOCK_PROCESS_CPUTIME_ID: c_int = linux_raw_sys::general::CLOCK_PROCESS_CPUTIME_ID as _; +#[cfg(any(feature = "thread", feature = "time", target_arch = "x86"))] +pub(crate) const CLOCK_BOOTTIME: c_int = linux_raw_sys::general::CLOCK_BOOTTIME as _; +#[cfg(any(feature = "thread", feature = "time", target_arch = "x86"))] +pub(crate) const CLOCK_BOOTTIME_ALARM: c_int = linux_raw_sys::general::CLOCK_BOOTTIME_ALARM as _; +#[cfg(any(feature = "thread", feature = "time", target_arch = "x86"))] +pub(crate) const CLOCK_TAI: c_int = linux_raw_sys::general::CLOCK_TAI as _; +#[cfg(any(feature = "thread", feature = "time", target_arch = "x86"))] +pub(crate) const CLOCK_REALTIME_ALARM: c_int = linux_raw_sys::general::CLOCK_REALTIME_ALARM as _; #[cfg(feature = "system")] mod reboot_symbols { diff --git a/vendor/rustix/src/backend/linux_raw/conv.rs b/vendor/rustix/src/backend/linux_raw/conv.rs index 4b3c15d7a..f0de45a2b 100644 --- a/vendor/rustix/src/backend/linux_raw/conv.rs +++ b/vendor/rustix/src/backend/linux_raw/conv.rs @@ -15,7 +15,7 @@ use super::c; use super::fd::{AsRawFd, BorrowedFd, FromRawFd, RawFd}; -#[cfg(feature = "runtime")] +#[cfg(any(feature = "event", feature = "runtime"))] use super::io::errno::try_decode_error; #[cfg(target_pointer_width = "64")] use super::io::errno::try_decode_u64; @@ -303,6 +303,7 @@ pub(super) fn socklen_t<'a, Num: ArgNumber>(i: socklen_t) -> ArgReg<'a, Num> { not(feature = "use-explicitly-provided-auxv"), any( feature = "param", + feature = "process", feature = "runtime", feature = "time", target_arch = "x86", @@ -622,7 +623,6 @@ 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 { @@ -874,7 +874,7 @@ pub(super) unsafe fn ret(raw: RetReg<R0>) -> io::Result<()> { /// /// The caller must ensure that this is the return value of a syscall which /// doesn't return on success. -#[cfg(feature = "runtime")] +#[cfg(any(feature = "event", feature = "runtime"))] #[inline] pub(super) unsafe fn ret_error(raw: RetReg<R0>) -> io::Errno { try_decode_error(raw) diff --git a/vendor/rustix/src/backend/linux_raw/event/epoll.rs b/vendor/rustix/src/backend/linux_raw/event/epoll.rs index 6aa84d7aa..fb6a04c8e 100644 --- a/vendor/rustix/src/backend/linux_raw/event/epoll.rs +++ b/vendor/rustix/src/backend/linux_raw/event/epoll.rs @@ -262,8 +262,8 @@ pub fn wait(epoll: impl AsFd, event_list: &mut EventVec, timeout: c::c_int) -> i /// An iterator over the `Event`s in an `EventVec`. pub struct Iter<'a> { /// Use `Copied` to copy the struct, since `Event` is `packed` on some - /// platforms, and it's common for users to directly destructure it, - /// which would lead to errors about forming references to packed fields. + /// platforms, and it's common for users to directly destructure it, which + /// would lead to errors about forming references to packed fields. iter: core::iter::Copied<slice::Iter<'a, Event>>, } 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 51c222e62..9de43f263 100644 --- a/vendor/rustix/src/backend/linux_raw/event/poll_fd.rs +++ b/vendor/rustix/src/backend/linux_raw/event/poll_fd.rs @@ -4,7 +4,7 @@ use bitflags::bitflags; bitflags! { /// `POLL*` flags for use with [`poll`]. /// - /// [`poll`]: crate::io::poll + /// [`poll`]: crate::event::poll #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct PollFlags: u16 { diff --git a/vendor/rustix/src/backend/linux_raw/event/syscalls.rs b/vendor/rustix/src/backend/linux_raw/event/syscalls.rs index 6cb8d3d96..0ae775339 100644 --- a/vendor/rustix/src/backend/linux_raw/event/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/event/syscalls.rs @@ -9,7 +9,7 @@ use crate::backend::c; #[cfg(feature = "alloc")] 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, + by_ref, c_int, c_uint, raw_fd, ret, ret_error, ret_owned_fd, ret_usize, slice_mut, zero, }; use crate::event::{epoll, EventfdFlags, PollFd}; use crate::fd::{BorrowedFd, OwnedFd}; @@ -131,3 +131,22 @@ pub(crate) fn epoll_wait( pub(crate) fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result<OwnedFd> { unsafe { ret_owned_fd(syscall_readonly!(__NR_eventfd2, c_uint(initval), flags)) } } + +#[inline] +pub(crate) fn pause() { + unsafe { + #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] + let error = ret_error(syscall_readonly!( + __NR_ppoll, + zero(), + zero(), + zero(), + zero() + )); + + #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] + let error = ret_error(syscall_readonly!(__NR_pause)); + + debug_assert_eq!(error, io::Errno::INTR); + } +} diff --git a/vendor/rustix/src/backend/linux_raw/event/types.rs b/vendor/rustix/src/backend/linux_raw/event/types.rs index eb34bd0b3..01611f673 100644 --- a/vendor/rustix/src/backend/linux_raw/event/types.rs +++ b/vendor/rustix/src/backend/linux_raw/event/types.rs @@ -4,7 +4,7 @@ use bitflags::bitflags; bitflags! { /// `EFD_*` flags for use with [`eventfd`]. /// - /// [`eventfd`]: crate::io::eventfd + /// [`eventfd`]: crate::event::eventfd #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct EventfdFlags: c::c_uint { diff --git a/vendor/rustix/src/backend/linux_raw/fs/dir.rs b/vendor/rustix/src/backend/linux_raw/fs/dir.rs index ea1017957..dbddd58f1 100644 --- a/vendor/rustix/src/backend/linux_raw/fs/dir.rs +++ b/vendor/rustix/src/backend/linux_raw/fs/dir.rs @@ -32,8 +32,26 @@ pub struct Dir { } impl Dir { - /// Construct a `Dir` that reads entries from the given directory - /// file descriptor. + /// Take ownership of `fd` and construct a `Dir` that reads entries from + /// the given directory file descriptor. + #[inline] + pub fn new<Fd: Into<OwnedFd>>(fd: Fd) -> io::Result<Self> { + Self::_new(fd.into()) + } + + #[inline] + fn _new(fd: OwnedFd) -> io::Result<Self> { + Ok(Self { + fd, + any_errors: false, + rewind: false, + buf: Vec::new(), + pos: 0, + }) + } + + /// Borrow `fd` and construct a `Dir` that reads entries from the given + /// directory file descriptor. #[inline] pub fn read_from<Fd: AsFd>(fd: Fd) -> io::Result<Self> { Self::_read_from(fd.as_fd()) @@ -157,6 +175,7 @@ impl Dir { })) } + #[must_use] fn read_more(&mut self) -> Option<io::Result<()>> { // The first few times we're called, we allocate a relatively small // buffer, because many directories are small. If we're called more, @@ -292,5 +311,5 @@ fn dir_iterator_handles_io_errors() { crate::io::dup2(&file_fd, &mut dir.fd).unwrap(); assert!(matches!(dir.next(), Some(Err(_)))); - assert!(matches!(dir.next(), None)); + assert!(dir.next().is_none()); } diff --git a/vendor/rustix/src/backend/linux_raw/fs/mod.rs b/vendor/rustix/src/backend/linux_raw/fs/mod.rs index ba72c5b6d..9f53c5dba 100644 --- a/vendor/rustix/src/backend/linux_raw/fs/mod.rs +++ b/vendor/rustix/src/backend/linux_raw/fs/mod.rs @@ -6,8 +6,8 @@ pub(crate) mod syscalls; pub(crate) mod types; // TODO: Fix linux-raw-sys to define ioctl codes for sparc. -#[cfg(all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64")))] +#[cfg(any(target_arch = "sparc", target_arch = "sparc64"))] pub(crate) const EXT4_IOC_RESIZE_FS: u32 = 0x8008_6610; -#[cfg(all(linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))))] +#[cfg(not(any(target_arch = "sparc", target_arch = "sparc64")))] pub(crate) use linux_raw_sys::ioctl::EXT4_IOC_RESIZE_FS; diff --git a/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs b/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs index f856fa8b0..5f15f5c93 100644 --- a/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs @@ -8,9 +8,11 @@ use crate::backend::c; use crate::backend::conv::fs::oflags_for_open_how; +#[cfg(not(feature = "linux_4_11"))] +use crate::backend::conv::zero; use crate::backend::conv::{ by_ref, c_int, c_uint, dev_t, opt_mut, pass_usize, raw_fd, ret, ret_c_int, ret_c_uint, - ret_infallible, ret_owned_fd, ret_usize, size_of, slice, slice_mut, zero, + ret_infallible, ret_owned_fd, ret_usize, size_of, slice, slice_mut, }; #[cfg(target_pointer_width = "64")] use crate::backend::conv::{loff_t, loff_t_from_u64, ret_u64}; @@ -839,13 +841,15 @@ pub(crate) fn statx( } } +#[cfg(not(feature = "linux_4_11"))] #[inline] pub(crate) fn is_statx_available() -> bool { unsafe { // Call `statx` with null pointers so that if it fails for any reason - // other than `EFAULT`, we know it's not supported. + // other than `EFAULT`, we know it's not supported. This can use + // "readonly" because we don't pass it a buffer to mutate. matches!( - ret(syscall!( + ret(syscall_readonly!( __NR_statx, raw_fd(AT_FDCWD), zero(), @@ -957,7 +961,6 @@ pub(crate) fn readlink(path: &CStr, buf: &mut [u8]) -> io::Result<usize> { } } -#[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 85fe018a3..71ee9f52e 100644 --- a/vendor/rustix/src/backend/linux_raw/fs/types.rs +++ b/vendor/rustix/src/backend/linux_raw/fs/types.rs @@ -197,13 +197,13 @@ bitflags! { /// `O_DIRECTORY` const DIRECTORY = linux_raw_sys::general::O_DIRECTORY; - /// `O_DSYNC`. Linux 2.6.32 only supports `O_SYNC`. + /// `O_DSYNC`. const DSYNC = linux_raw_sys::general::O_SYNC; /// `O_EXCL` const EXCL = linux_raw_sys::general::O_EXCL; - /// `O_FSYNC`. Linux 2.6.32 only supports `O_SYNC`. + /// `O_FSYNC`. const FSYNC = linux_raw_sys::general::O_SYNC; /// `O_NOFOLLOW` @@ -226,7 +226,7 @@ bitflags! { /// `O_NOCTTY` const NOCTTY = linux_raw_sys::general::O_NOCTTY; - /// `O_RSYNC`. Linux 2.6.32 only supports `O_SYNC`. + /// `O_RSYNC`. const RSYNC = linux_raw_sys::general::O_SYNC; /// `O_SYNC` diff --git a/vendor/rustix/src/backend/linux_raw/io/errno.rs b/vendor/rustix/src/backend/linux_raw/io/errno.rs index 8247faa1c..6771ba2b2 100644 --- a/vendor/rustix/src/backend/linux_raw/io/errno.rs +++ b/vendor/rustix/src/backend/linux_raw/io/errno.rs @@ -236,7 +236,7 @@ pub(in crate::backend) unsafe fn try_decode_void<Num: RetNumber>( /// # Safety /// /// This must only be used with syscalls which do not return on success. -#[cfg(feature = "runtime")] +#[cfg(any(feature = "event", feature = "runtime"))] #[inline] pub(in crate::backend) unsafe fn try_decode_error<Num: RetNumber>(raw: RetReg<Num>) -> io::Errno { debug_assert!(raw.is_in_range(-4095..0)); diff --git a/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs b/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs index 3d4274cfe..361f11157 100644 --- a/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs @@ -6,10 +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, + Advice, MapFlags, MlockAllFlags, MlockFlags, MprotectFlags, MremapFlags, MsyncFlags, ProtFlags, UserfaultfdFlags, }; use crate::backend::c; @@ -221,7 +219,6 @@ pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result<OwnedFd> /// 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, @@ -235,7 +232,6 @@ pub(crate) fn mlockall(flags: MlockAllFlags) -> io::Result<()> { /// 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 b5e36640d..68898f58b 100644 --- a/vendor/rustix/src/backend/linux_raw/mm/types.rs +++ b/vendor/rustix/src/backend/linux_raw/mm/types.rs @@ -6,7 +6,7 @@ bitflags! { /// /// For `PROT_NONE`, use `ProtFlags::empty()`. /// - /// [`mmap`]: crate::io::mmap + /// [`mmap`]: crate::mm::mmap #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct ProtFlags: u32 { @@ -27,7 +27,7 @@ bitflags! { /// /// For `PROT_NONE`, use `MprotectFlags::empty()`. /// - /// [`mprotect`]: crate::io::mprotect + /// [`mprotect`]: crate::mm::mprotect #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MprotectFlags: u32 { @@ -66,8 +66,8 @@ bitflags! { /// /// For `MAP_ANONYMOUS` (aka `MAP_ANON`), see [`mmap_anonymous`]. /// - /// [`mmap`]: crate::io::mmap - /// [`mmap_anonymous`]: crates::io::mmap_anonymous + /// [`mmap`]: crate::mm::mmap + /// [`mmap_anonymous`]: crates::mm::mmap_anonymous #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MapFlags: u32 { @@ -116,8 +116,8 @@ bitflags! { /// /// For `MREMAP_FIXED`, see [`mremap_fixed`]. /// - /// [`mremap`]: crate::io::mremap - /// [`mremap_fixed`]: crate::io::mremap_fixed + /// [`mremap`]: crate::mm::mremap + /// [`mremap_fixed`]: crate::mm::mremap_fixed #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MremapFlags: u32 { @@ -134,7 +134,7 @@ bitflags! { bitflags! { /// `MS_*` flags for use with [`msync`]. /// - /// [`msync`]: crate::io::msync + /// [`msync`]: crate::mm::msync #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MsyncFlags: u32 { @@ -156,7 +156,7 @@ bitflags! { bitflags! { /// `MLOCK_*` flags for use with [`mlock_with`]. /// - /// [`mlock_with`]: crate::io::mlock_with + /// [`mlock_with`]: crate::mm::mlock_with #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MlockFlags: u32 { @@ -212,9 +212,9 @@ pub enum Advice { LinuxMergeable = linux_raw_sys::general::MADV_MERGEABLE, /// `MADV_UNMERGEABLE` LinuxUnmergeable = linux_raw_sys::general::MADV_UNMERGEABLE, - /// `MADV_HUGEPAGE` (since Linux 2.6.38) + /// `MADV_HUGEPAGE` LinuxHugepage = linux_raw_sys::general::MADV_HUGEPAGE, - /// `MADV_NOHUGEPAGE` (since Linux 2.6.38) + /// `MADV_NOHUGEPAGE` LinuxNoHugepage = linux_raw_sys::general::MADV_NOHUGEPAGE, /// `MADV_DONTDUMP` (since Linux 3.4) LinuxDontDump = linux_raw_sys::general::MADV_DONTDUMP, @@ -249,7 +249,7 @@ impl Advice { bitflags! { /// `O_*` flags for use with [`userfaultfd`]. /// - /// [`userfaultfd`]: crate::io::userfaultfd + /// [`userfaultfd`]: crate::mm::userfaultfd #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct UserfaultfdFlags: c::c_uint { @@ -263,7 +263,6 @@ bitflags! { } } -#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] bitflags! { /// `MCL_*` flags for use with [`mlockall`]. /// diff --git a/vendor/rustix/src/backend/linux_raw/mod.rs b/vendor/rustix/src/backend/linux_raw/mod.rs index 388f573dc..0d4e5332d 100644 --- a/vendor/rustix/src/backend/linux_raw/mod.rs +++ b/vendor/rustix/src/backend/linux_raw/mod.rs @@ -18,9 +18,9 @@ mod arch; mod conv; mod reg; -#[cfg(any(feature = "time", target_arch = "x86"))] +#[cfg(any(feature = "time", feature = "process", target_arch = "x86"))] mod vdso; -#[cfg(any(feature = "time", target_arch = "x86"))] +#[cfg(any(feature = "time", feature = "process", target_arch = "x86"))] mod vdso_wrappers; #[cfg(feature = "event")] @@ -32,6 +32,7 @@ pub(crate) mod event; not(feature = "use-explicitly-provided-auxv"), any( feature = "param", + feature = "process", feature = "runtime", feature = "time", target_arch = "x86", @@ -52,6 +53,7 @@ pub(crate) mod mount; // for deprecated mount functions in "fs" pub(crate) mod net; #[cfg(any( feature = "param", + feature = "process", feature = "runtime", feature = "time", target_arch = "x86", diff --git a/vendor/rustix/src/backend/linux_raw/mount/types.rs b/vendor/rustix/src/backend/linux_raw/mount/types.rs index 3a797ab77..43a2f7b49 100644 --- a/vendor/rustix/src/backend/linux_raw/mount/types.rs +++ b/vendor/rustix/src/backend/linux_raw/mount/types.rs @@ -292,9 +292,9 @@ bitflags! { } bitflags! { - /// `MS_*` constants for use with [`change_mount`]. + /// `MS_*` constants for use with [`mount_change`]. /// - /// [`change_mount`]: crate::mount::change_mount + /// [`mount_change`]: crate::mount::mount_change #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MountPropagationFlags: c::c_uint { diff --git a/vendor/rustix/src/backend/linux_raw/param/auxv.rs b/vendor/rustix/src/backend/linux_raw/param/auxv.rs index fbbcdea29..b9ac27eec 100644 --- a/vendor/rustix/src/backend/linux_raw/param/auxv.rs +++ b/vendor/rustix/src/backend/linux_raw/param/auxv.rs @@ -25,7 +25,7 @@ use linux_raw_sys::general::{ }; #[cfg(feature = "runtime")] use linux_raw_sys::general::{ - AT_EGID, AT_ENTRY, AT_EUID, AT_GID, AT_PHDR, AT_PHENT, AT_PHNUM, AT_SECURE, AT_UID, + AT_EGID, AT_ENTRY, AT_EUID, AT_GID, AT_PHDR, AT_PHENT, AT_PHNUM, AT_RANDOM, AT_SECURE, AT_UID, }; #[cfg(feature = "param")] @@ -145,6 +145,19 @@ pub(crate) fn entry() -> usize { entry } +#[cfg(feature = "runtime")] +#[inline] +pub(crate) fn random() -> *const [u8; 16] { + let mut random = RANDOM.load(Relaxed); + + if random.is_null() { + init_auxv(); + random = RANDOM.load(Relaxed); + } + + random +} + static PAGE_SIZE: AtomicUsize = AtomicUsize::new(0); static CLOCK_TICKS_PER_SECOND: AtomicUsize = AtomicUsize::new(0); static HWCAP: AtomicUsize = AtomicUsize::new(0); @@ -161,6 +174,8 @@ static PHENT: AtomicUsize = AtomicUsize::new(0); static PHNUM: AtomicUsize = AtomicUsize::new(0); #[cfg(feature = "runtime")] static ENTRY: AtomicUsize = AtomicUsize::new(0); +#[cfg(feature = "runtime")] +static RANDOM: AtomicPtr<[u8; 16]> = AtomicPtr::new(null_mut()); #[cfg(feature = "alloc")] fn pr_get_auxv() -> crate::io::Result<Vec<u8>> { @@ -207,7 +222,7 @@ fn init_auxv() { Ok(buffer) => { // SAFETY: We assume the kernel returns a valid auxv. unsafe { - init_from_aux_iter(AuxPointer(buffer.as_ptr().cast())); + init_from_aux_iter(AuxPointer(buffer.as_ptr().cast())).unwrap(); } return; } @@ -235,6 +250,7 @@ fn init_auxv() { /// Process auxv entries from the open file `auxv`. #[cfg(feature = "alloc")] #[cold] +#[must_use] fn init_from_auxv_file(auxv: OwnedFd) -> Option<()> { let mut buffer = Vec::<u8>::with_capacity(512); loop { @@ -271,6 +287,7 @@ fn init_from_auxv_file(auxv: OwnedFd) -> Option<()> { /// The buffer contains `Elf_aux_t` elements, though it need not be aligned; /// function uses `read_unaligned` to read from it. #[cold] +#[must_use] unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Option<()> { let mut pagesz = 0; let mut clktck = 0; @@ -296,6 +313,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti let mut gid = None; #[cfg(feature = "runtime")] let mut egid = None; + #[cfg(feature = "runtime")] + let mut random = null_mut(); for Elf_auxv_t { a_type, a_val } in aux_iter { match a_type as _ { @@ -307,7 +326,11 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti AT_SYSINFO_EHDR => sysinfo_ehdr = check_elf_base(a_val as *mut _)?.as_ptr(), AT_BASE => { - let _ = check_elf_base(a_val.cast())?; + // The `AT_BASE` value can be NULL in a static executable that + // doesn't use a dynamic linker. If so, ignore it. + if !a_val.is_null() { + let _ = check_elf_base(a_val.cast())?; + } } #[cfg(feature = "runtime")] @@ -328,6 +351,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti AT_PHENT => phent = a_val as usize, #[cfg(feature = "runtime")] AT_ENTRY => entry = a_val as usize, + #[cfg(feature = "runtime")] + AT_RANDOM => random = check_raw_pointer::<[u8; 16]>(a_val as *mut _)?.as_ptr(), AT_NULL => break, _ => (), @@ -361,6 +386,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti PHNUM.store(phnum, Relaxed); #[cfg(feature = "runtime")] ENTRY.store(entry, Relaxed); + #[cfg(feature = "runtime")] + RANDOM.store(random, Relaxed); Some(()) } @@ -371,6 +398,7 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti /// which hopefully holds the value of the kernel-provided vDSO in memory. Do a /// series of checks to be as sure as we can that it's safe to use. #[cold] +#[must_use] unsafe fn check_elf_base(base: *const Elf_Ehdr) -> Option<NonNull<Elf_Ehdr>> { // If we're reading a 64-bit auxv on a 32-bit platform, we'll see a zero // `a_val` because `AT_*` values are never greater than `u32::MAX`. Zero is @@ -471,7 +499,7 @@ impl Iterator for AuxFile { Ok(0) => panic!("unexpected end of auxv file"), Ok(n) => slice = &mut slice[n..], Err(crate::io::Errno::INTR) => continue, - Err(err) => Err(err).unwrap(), + Err(err) => panic!("{:?}", err), } } Some(unsafe { read_unaligned(buf.as_ptr().cast()) }) diff --git a/vendor/rustix/src/backend/linux_raw/param/init.rs b/vendor/rustix/src/backend/linux_raw/param/init.rs index a63212507..fe29e9c04 100644 --- a/vendor/rustix/src/backend/linux_raw/param/init.rs +++ b/vendor/rustix/src/backend/linux_raw/param/init.rs @@ -18,7 +18,7 @@ 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, AT_SECURE}; +use linux_raw_sys::general::{AT_ENTRY, AT_PHDR, AT_PHENT, AT_PHNUM, AT_RANDOM, AT_SECURE}; #[cfg(feature = "param")] #[inline] @@ -84,6 +84,12 @@ pub(crate) fn entry() -> usize { unsafe { ENTRY.load(Ordering::Relaxed) } } +#[cfg(feature = "runtime")] +#[inline] +pub(crate) fn random() -> *const [u8; 16] { + unsafe { RANDOM.load(Ordering::Relaxed) } +} + static mut PAGE_SIZE: AtomicUsize = AtomicUsize::new(0); static mut CLOCK_TICKS_PER_SECOND: AtomicUsize = AtomicUsize::new(0); static mut HWCAP: AtomicUsize = AtomicUsize::new(0); @@ -103,6 +109,8 @@ static mut PHENT: AtomicUsize = AtomicUsize::new(0); static mut PHNUM: AtomicUsize = AtomicUsize::new(0); #[cfg(feature = "runtime")] static mut ENTRY: AtomicUsize = AtomicUsize::new(0); +#[cfg(feature = "runtime")] +static mut RANDOM: AtomicPtr<[u8; 16]> = AtomicPtr::new(NonNull::dangling().as_ptr()); /// When "use-explicitly-provided-auxv" is enabled, we export a function to be /// called during initialization, and passed a pointer to the original @@ -152,6 +160,8 @@ unsafe fn init_from_auxp(mut auxp: *const Elf_auxv_t) { AT_PHENT => PHENT.store(a_val as usize, Ordering::Relaxed), #[cfg(feature = "runtime")] AT_ENTRY => ENTRY.store(a_val as usize, Ordering::Relaxed), + #[cfg(feature = "runtime")] + AT_RANDOM => RANDOM.store(a_val.cast::<[u8; 16]>(), Ordering::Relaxed), AT_NULL => break, _ => (), 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 311cf961b..cfdd7a543 100644 --- a/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs +++ b/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs @@ -33,6 +33,8 @@ const AT_PHNUM: c::c_ulong = 5; #[cfg(feature = "runtime")] const AT_ENTRY: c::c_ulong = 9; const AT_HWCAP: c::c_ulong = 16; +#[cfg(feature = "runtime")] +const AT_RANDOM: c::c_ulong = 25; const AT_HWCAP2: c::c_ulong = 26; const AT_SECURE: c::c_ulong = 23; const AT_EXECFN: c::c_ulong = 31; @@ -68,6 +70,8 @@ fn test_abi() { const_assert_eq!(self::AT_PHNUM, ::libc::AT_PHNUM); #[cfg(feature = "runtime")] const_assert_eq!(self::AT_ENTRY, ::libc::AT_ENTRY); + #[cfg(feature = "runtime")] + const_assert_eq!(self::AT_RANDOM, ::libc::AT_RANDOM); } #[cfg(feature = "param")] @@ -163,3 +167,9 @@ pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr { pub(crate) fn entry() -> usize { unsafe { getauxval(AT_ENTRY) as usize } } + +#[cfg(feature = "runtime")] +#[inline] +pub(crate) fn random() -> *const [u8; 16] { + unsafe { getauxval(AT_RANDOM) as *const [u8; 16] } +} diff --git a/vendor/rustix/src/backend/linux_raw/pipe/types.rs b/vendor/rustix/src/backend/linux_raw/pipe/types.rs index fdddb89e1..cfcb75477 100644 --- a/vendor/rustix/src/backend/linux_raw/pipe/types.rs +++ b/vendor/rustix/src/backend/linux_raw/pipe/types.rs @@ -5,7 +5,7 @@ use core::marker::PhantomData; bitflags! { /// `O_*` constants for use with [`pipe_with`]. /// - /// [`pipe_with`]: crate::io::pipe_with + /// [`pipe_with`]: crate::pipe::pipe_with #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct PipeFlags: c::c_uint { diff --git a/vendor/rustix/src/backend/linux_raw/process/syscalls.rs b/vendor/rustix/src/backend/linux_raw/process/syscalls.rs index 931f2ff2a..130ee4c93 100644 --- a/vendor/rustix/src/backend/linux_raw/process/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/process/syscalls.rs @@ -36,6 +36,32 @@ use {crate::backend::conv::ret_c_uint_infallible, crate::fs::Mode}; #[cfg(feature = "alloc")] use {crate::backend::conv::slice_just_addr_mut, crate::process::Gid}; +// `sched_getcpu` has special optimizations via the vDSO on some architectures. +#[cfg(any( + target_arch = "x86_64", + target_arch = "x86", + target_arch = "riscv64", + target_arch = "powerpc64" +))] +pub(crate) use crate::backend::vdso_wrappers::sched_getcpu; + +// `sched_getcpu` on platforms without a vDSO entry for it. +#[cfg(not(any( + target_arch = "x86_64", + target_arch = "x86", + target_arch = "riscv64", + target_arch = "powerpc64" +)))] +#[inline] +pub(crate) fn sched_getcpu() -> usize { + let mut cpu = MaybeUninit::<u32>::uninit(); + unsafe { + let r = ret(syscall!(__NR_getcpu, &mut cpu, zero(), zero())); + debug_assert!(r.is_ok()); + cpu.assume_init() as usize + } +} + #[cfg(feature = "fs")] #[inline] pub(crate) fn chdir(filename: &CStr) -> io::Result<()> { diff --git a/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs b/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs index 1bc461c04..12162fd32 100644 --- a/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs @@ -9,8 +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, ret_void_star, size_of, - zero, + by_ref, c_int, c_uint, ret, ret_c_int, ret_c_int_infallible, ret_error, ret_infallible, + ret_void_star, size_of, zero, }; #[cfg(feature = "fs")] use crate::fd::BorrowedFd; @@ -18,8 +18,8 @@ use crate::ffi::CStr; #[cfg(feature = "fs")] use crate::fs::AtFlags; use crate::io; -use crate::pid::Pid; -use crate::runtime::{How, Sigaction, Siginfo, Sigset, Stack}; +use crate::pid::{Pid, RawPid}; +use crate::runtime::{Fork, How, Sigaction, Siginfo, Sigset, Stack}; use crate::signal::Signal; use crate::timespec::Timespec; use crate::utils::option_as_ptr; @@ -28,21 +28,53 @@ use core::mem::MaybeUninit; #[cfg(target_pointer_width = "32")] use linux_raw_sys::general::__kernel_old_timespec; use linux_raw_sys::general::kernel_sigset_t; -use linux_raw_sys::prctl::PR_SET_NAME; #[cfg(target_arch = "x86_64")] -use {crate::backend::conv::ret_infallible, linux_raw_sys::general::ARCH_SET_FS}; +use linux_raw_sys::general::ARCH_SET_FS; +use linux_raw_sys::prctl::PR_SET_NAME; #[inline] -pub(crate) unsafe fn fork() -> io::Result<Option<Pid>> { +pub(crate) unsafe fn fork() -> io::Result<Fork> { + let mut child_pid = MaybeUninit::<RawPid>::uninit(); + + // Unix `fork` only returns the child PID in the parent; we'd like it in + // the child too, so set `CLONE_CHILD_SETTID` and pass in the address of + // a memory location to store it to in the child. + // + // Architectures differ on the order of the parameters. + #[cfg(target_arch = "x86_64")] let pid = ret_c_int(syscall_readonly!( __NR_clone, - c_int(c::SIGCHLD), - zero(), + c_int(c::SIGCHLD | c::CLONE_CHILD_SETTID), zero(), zero(), + &mut child_pid, zero() ))?; - Ok(Pid::from_raw(pid)) + #[cfg(any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "powerpc64", + target_arch = "riscv64", + target_arch = "x86" + ))] + let pid = ret_c_int(syscall_readonly!( + __NR_clone, + c_int(c::SIGCHLD | c::CLONE_CHILD_SETTID), + zero(), + zero(), + zero(), + &mut child_pid + ))?; + + Ok(if let Some(pid) = Pid::from_raw(pid) { + Fork::Parent(pid) + } else { + Fork::Child(Pid::from_raw_unchecked(child_pid.assume_init())) + }) } #[cfg(feature = "fs")] @@ -167,6 +199,30 @@ pub(crate) unsafe fn sigprocmask(how: How, new: Option<&Sigset>) -> io::Result<S } #[inline] +pub(crate) fn sigpending() -> Sigset { + let mut pending = MaybeUninit::<Sigset>::uninit(); + unsafe { + ret_infallible(syscall!( + __NR_rt_sigpending, + &mut pending, + size_of::<kernel_sigset_t, _>() + )); + pending.assume_init() + } +} + +#[inline] +pub(crate) fn sigsuspend(set: &Sigset) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_rt_sigsuspend, + by_ref(set), + size_of::<kernel_sigset_t, _>() + )) + } +} + +#[inline] pub(crate) fn sigwait(set: &Sigset) -> io::Result<Signal> { unsafe { match Signal::from_raw(ret_c_int(syscall_readonly!( @@ -268,6 +324,6 @@ pub(crate) fn exit_group(code: c::c_int) -> ! { #[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. + // This is non-`readonly`, to prevent loads from being reordered past it. ret_void_star(syscall!(__NR_brk, addr)) } diff --git a/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs b/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs index d2fe91236..5a24c0a74 100644 --- a/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs @@ -86,6 +86,14 @@ pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result<Pid> { let mut result = MaybeUninit::<c::pid_t>::uninit(); ret(syscall!(__NR_ioctl, fd, c_uint(TIOCGPGRP), &mut result))?; let pid = result.assume_init(); + + // This doesn't appear to be documented, but it appears `tcsetpgrp` can + // succceed and set the pid to 0 if we pass it a pseudo-terminal device + // fd. For now, fail with `OPNOTSUPP`. + if pid == 0 { + return Err(io::Errno::OPNOTSUPP); + } + Ok(Pid::from_raw_unchecked(pid)) } } @@ -166,7 +174,7 @@ pub(crate) fn tcgetsid(fd: BorrowedFd<'_>) -> io::Result<Pid> { #[inline] pub(crate) fn tcsetwinsize(fd: BorrowedFd<'_>, winsize: Winsize) -> io::Result<()> { unsafe { - ret(syscall!( + ret(syscall_readonly!( __NR_ioctl, fd, c_uint(TIOCSWINSZ), @@ -177,7 +185,15 @@ pub(crate) fn tcsetwinsize(fd: BorrowedFd<'_>, winsize: Winsize) -> io::Result<( #[inline] pub(crate) fn tcsetpgrp(fd: BorrowedFd<'_>, pid: Pid) -> io::Result<()> { - unsafe { ret(syscall!(__NR_ioctl, fd, c_uint(TIOCSPGRP), pid)) } + let raw_pid: c::c_int = pid.as_raw_nonzero().get(); + unsafe { + ret(syscall_readonly!( + __NR_ioctl, + fd, + c_uint(TIOCSPGRP), + by_ref(&raw_pid) + )) + } } /// A wrapper around a conceptual `cfsetspeed` which handles an arbitrary diff --git a/vendor/rustix/src/backend/linux_raw/time/syscalls.rs b/vendor/rustix/src/backend/linux_raw/time/syscalls.rs index 27c3652a4..d20bcfac6 100644 --- a/vendor/rustix/src/backend/linux_raw/time/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/time/syscalls.rs @@ -104,7 +104,7 @@ unsafe fn clock_settime_old(which_clock: ClockId, timespec: Timespec) -> io::Res #[cfg(feature = "time")] #[inline] pub(crate) fn timerfd_create(clockid: TimerfdClockId, flags: TimerfdFlags) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(syscall!(__NR_timerfd_create, clockid, flags)) } + unsafe { ret_owned_fd(syscall_readonly!(__NR_timerfd_create, clockid, flags)) } } #[cfg(feature = "time")] diff --git a/vendor/rustix/src/backend/linux_raw/time/types.rs b/vendor/rustix/src/backend/linux_raw/time/types.rs index f3e653b0a..c26812c5d 100644 --- a/vendor/rustix/src/backend/linux_raw/time/types.rs +++ b/vendor/rustix/src/backend/linux_raw/time/types.rs @@ -16,9 +16,11 @@ bitflags! { #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct TimerfdFlags: c::c_uint { /// `TFD_NONBLOCK` + #[doc(alias = "TFD_NONBLOCK")] const NONBLOCK = linux_raw_sys::general::TFD_NONBLOCK; /// `TFD_CLOEXEC` + #[doc(alias = "TFD_CLOEXEC")] const CLOEXEC = linux_raw_sys::general::TFD_CLOEXEC; /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> @@ -34,9 +36,11 @@ bitflags! { #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct TimerfdTimerFlags: c::c_uint { /// `TFD_TIMER_ABSTIME` + #[doc(alias = "TFD_TIMER_ABSTIME")] const ABSTIME = linux_raw_sys::general::TFD_TIMER_ABSTIME; /// `TFD_TIMER_CANCEL_ON_SET` + #[doc(alias = "TFD_TIMER_CANCEL_ON_SET")] const CANCEL_ON_SET = linux_raw_sys::general::TFD_TIMER_CANCEL_ON_SET; /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> @@ -57,6 +61,7 @@ pub enum TimerfdClockId { /// epoch, 1970-01-01T00:00:00Z. The clock is externally settable, so it is /// not monotonic. Successive reads may see decreasing times, so it isn't /// reliable for measuring durations. + #[doc(alias = "CLOCK_REALTIME")] Realtime = linux_raw_sys::general::CLOCK_REALTIME, /// `CLOCK_MONOTONIC`—A clock that tells an abstract time. @@ -67,12 +72,14 @@ pub enum TimerfdClockId { /// /// This clock does not advance while the system is suspended; see /// `Boottime` for a clock that does. + #[doc(alias = "CLOCK_MONOTONIC")] Monotonic = linux_raw_sys::general::CLOCK_MONOTONIC, /// `CLOCK_BOOTTIME`—Like `Monotonic`, but advances while suspended. /// /// This clock is similar to `Monotonic`, but does advance while the system /// is suspended. + #[doc(alias = "CLOCK_BOOTTIME")] Boottime = linux_raw_sys::general::CLOCK_BOOTTIME, /// `CLOCK_REALTIME_ALARM`—Like `Realtime`, but wakes a suspended system. @@ -80,6 +87,7 @@ pub enum TimerfdClockId { /// This clock is like `Realtime`, but can wake up a suspended system. /// /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. + #[doc(alias = "CLOCK_REALTIME_ALARM")] RealtimeAlarm = linux_raw_sys::general::CLOCK_REALTIME_ALARM, /// `CLOCK_BOOTTIME_ALARM`—Like `Boottime`, but wakes a suspended system. @@ -87,5 +95,6 @@ pub enum TimerfdClockId { /// This clock is like `Boottime`, but can wake up a suspended system. /// /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. + #[doc(alias = "CLOCK_BOOTTIME_ALARM")] BoottimeAlarm = linux_raw_sys::general::CLOCK_BOOTTIME_ALARM, } diff --git a/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs b/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs index 601dc1855..441738f8d 100644 --- a/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs +++ b/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs @@ -14,6 +14,14 @@ use super::reg::{ArgReg, RetReg, SyscallNumber, A0, A1, A2, A3, A4, A5, R0}; use super::vdso; #[cfg(target_arch = "x86")] use core::arch::global_asm; +#[cfg(feature = "process")] +#[cfg(any( + target_arch = "x86_64", + target_arch = "x86", + target_arch = "riscv64", + target_arch = "powerpc64" +))] +use core::ffi::c_void; use core::mem::transmute; use core::ptr::null_mut; use core::sync::atomic::AtomicPtr; @@ -21,14 +29,25 @@ use core::sync::atomic::Ordering::Relaxed; #[cfg(target_pointer_width = "32")] #[cfg(feature = "time")] use linux_raw_sys::general::timespec as __kernel_old_timespec; +#[cfg(any( + all( + feature = "process", + any( + target_arch = "x86_64", + target_arch = "x86", + target_arch = "riscv64", + target_arch = "powerpc64" + ) + ), + feature = "time" +))] +use {super::c, super::conv::ret, core::mem::MaybeUninit}; #[cfg(feature = "time")] use { - super::c, - super::conv::{c_int, ret}, + super::conv::c_int, crate::clockid::{ClockId, DynamicClockId}, crate::io, crate::timespec::Timespec, - core::mem::MaybeUninit, linux_raw_sys::general::{__kernel_clockid_t, __kernel_timespec}, }; @@ -67,14 +86,10 @@ pub(crate) fn clock_gettime_dynamic(which_clock: DynamicClockId<'_>) -> io::Resu ((!fd.as_raw_fd() << 3) | CLOCKFD) as __kernel_clockid_t } - DynamicClockId::RealtimeAlarm => { - linux_raw_sys::general::CLOCK_REALTIME_ALARM as __kernel_clockid_t - } - DynamicClockId::Tai => linux_raw_sys::general::CLOCK_TAI as __kernel_clockid_t, - DynamicClockId::Boottime => linux_raw_sys::general::CLOCK_BOOTTIME as __kernel_clockid_t, - DynamicClockId::BoottimeAlarm => { - linux_raw_sys::general::CLOCK_BOOTTIME_ALARM as __kernel_clockid_t - } + DynamicClockId::RealtimeAlarm => c::CLOCK_REALTIME_ALARM as __kernel_clockid_t, + DynamicClockId::Tai => c::CLOCK_TAI as __kernel_clockid_t, + DynamicClockId::Boottime => c::CLOCK_BOOTTIME as __kernel_clockid_t, + DynamicClockId::BoottimeAlarm => c::CLOCK_BOOTTIME_ALARM as __kernel_clockid_t, }; // SAFETY: `CLOCK_GETTIME` contains either null or the address of a @@ -96,6 +111,30 @@ pub(crate) fn clock_gettime_dynamic(which_clock: DynamicClockId<'_>) -> io::Resu } } +#[cfg(feature = "process")] +#[cfg(any( + target_arch = "x86_64", + target_arch = "x86", + target_arch = "riscv64", + target_arch = "powerpc64" +))] +#[inline] +pub(crate) fn sched_getcpu() -> usize { + // SAFETY: `GETCPU` contains either null or the address of a function with + // an ABI like libc `getcpu`, and calling it has the side effect of writing + // to the result buffers, and no others. + unsafe { + let mut cpu = MaybeUninit::<u32>::uninit(); + let callee = match transmute(GETCPU.load(Relaxed)) { + Some(callee) => callee, + None => init_getcpu(), + }; + let r0 = callee(cpu.as_mut_ptr(), null_mut(), null_mut()); + debug_assert_eq!(r0, 0); + cpu.assume_init() as usize + } +} + #[cfg(target_arch = "x86")] pub(super) mod x86_via_vdso { use super::{transmute, ArgReg, Relaxed, RetReg, SyscallNumber, A0, A1, A2, A3, A4, A5, R0}; @@ -223,6 +262,15 @@ pub(super) mod x86_via_vdso { #[cfg(feature = "time")] type ClockGettimeType = unsafe extern "C" fn(c::c_int, *mut Timespec) -> c::c_int; +#[cfg(feature = "process")] +#[cfg(any( + target_arch = "x86_64", + target_arch = "x86", + target_arch = "riscv64", + target_arch = "powerpc64" +))] +type GetcpuType = unsafe extern "C" fn(*mut u32, *mut u32, *mut c_void) -> c::c_int; + /// The underlying syscall functions are only called from asm, using the /// special syscall calling convention to pass arguments and return values, /// which the signature here doesn't reflect. @@ -239,6 +287,22 @@ fn init_clock_gettime() -> ClockGettimeType { unsafe { transmute(CLOCK_GETTIME.load(Relaxed)) } } +/// Initialize `GETCPU` and return its value. +#[cfg(feature = "process")] +#[cfg(any( + target_arch = "x86_64", + target_arch = "x86", + target_arch = "riscv64", + target_arch = "powerpc64" +))] +#[cold] +fn init_getcpu() -> GetcpuType { + init(); + // SAFETY: Load the function address from static storage that we just + // initialized. + unsafe { transmute(GETCPU.load(Relaxed)) } +} + /// Initialize `SYSCALL` and return its value. #[cfg(target_arch = "x86")] #[cold] @@ -254,6 +318,14 @@ fn init_syscall() -> SyscallType { struct Function; #[cfg(feature = "time")] static mut CLOCK_GETTIME: AtomicPtr<Function> = AtomicPtr::new(null_mut()); +#[cfg(feature = "process")] +#[cfg(any( + target_arch = "x86_64", + target_arch = "x86", + target_arch = "riscv64", + target_arch = "powerpc64" +))] +static mut GETCPU: AtomicPtr<Function> = AtomicPtr::new(null_mut()); #[cfg(target_arch = "x86")] static mut SYSCALL: AtomicPtr<Function> = AtomicPtr::new(null_mut()); @@ -315,6 +387,24 @@ unsafe fn _rustix_clock_gettime_via_syscall( ret(syscall!(__NR_clock_gettime, c_int(clockid), res)) } +#[cfg(feature = "process")] +#[cfg(any( + target_arch = "x86_64", + target_arch = "x86", + target_arch = "riscv64", + target_arch = "powerpc64" +))] +unsafe extern "C" fn rustix_getcpu_via_syscall( + cpu: *mut u32, + node: *mut u32, + unused: *mut c_void, +) -> c::c_int { + match ret(syscall!(__NR_getcpu, cpu, node, unused)) { + Ok(()) => 0, + Err(err) => err.raw_os_error().wrapping_neg(), + } +} + #[cfg(target_arch = "x86")] extern "C" { /// A symbol pointing to an `int 0x80` instruction. This “function” is only @@ -361,6 +451,24 @@ fn minimal_init() { .ok(); } + #[cfg(feature = "process")] + #[cfg(any( + target_arch = "x86_64", + target_arch = "x86", + target_arch = "riscv64", + target_arch = "powerpc64" + ))] + { + GETCPU + .compare_exchange( + null_mut(), + rustix_getcpu_via_syscall as *mut Function, + Relaxed, + Relaxed, + ) + .ok(); + } + #[cfg(target_arch = "x86")] { SYSCALL @@ -430,6 +538,60 @@ fn init() { } } + #[cfg(feature = "process")] + #[cfg(any( + target_arch = "x86_64", + target_arch = "x86", + target_arch = "riscv64", + target_arch = "powerpc64" + ))] + { + // Look up the platform-specific `getcpu` symbol as documented + // [here]. + // + // [here]: https://man7.org/linux/man-pages/man7/vdso.7.html + #[cfg(target_arch = "x86_64")] + let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_getcpu")); + #[cfg(target_arch = "x86")] + let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_getcpu")); + #[cfg(target_arch = "riscv64")] + let ptr = vdso.sym(cstr!("LINUX_4.15"), cstr!("__kernel_getcpu")); + #[cfg(target_arch = "powerpc64")] + let ptr = vdso.sym(cstr!("LINUX_2.6.15"), cstr!("__kernel_getcpu")); + + #[cfg(any( + target_arch = "x86_64", + target_arch = "riscv64", + target_arch = "powerpc64" + ))] + let ok = true; + + // On 32-bit x86, the symbol doesn't appear present sometimes. + #[cfg(target_arch = "x86")] + let ok = !ptr.is_null(); + + #[cfg(any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + let ok = false; + + if ok { + assert!(!ptr.is_null()); + + // 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 { + GETCPU.store(ptr.cast(), Relaxed); + } + } + } + // On x86, also look up the vsyscall entry point. #[cfg(target_arch = "x86")] { |