diff options
| author | Valentin Popov <valentin@popov.link> | 2024-01-08 00:21:28 +0300 | 
|---|---|---|
| committer | Valentin Popov <valentin@popov.link> | 2024-01-08 00:21:28 +0300 | 
| commit | 1b6a04ca5504955c571d1c97504fb45ea0befee4 (patch) | |
| tree | 7579f518b23313e8a9748a88ab6173d5e030b227 /vendor/rustix/src/backend/linux_raw/time | |
| parent | 5ecd8cf2cba827454317368b68571df0d13d7842 (diff) | |
| download | fparkan-1b6a04ca5504955c571d1c97504fb45ea0befee4.tar.xz fparkan-1b6a04ca5504955c571d1c97504fb45ea0befee4.zip  | |
Initial vendor packages
Signed-off-by: Valentin Popov <valentin@popov.link>
Diffstat (limited to 'vendor/rustix/src/backend/linux_raw/time')
| -rw-r--r-- | vendor/rustix/src/backend/linux_raw/time/mod.rs | 3 | ||||
| -rw-r--r-- | vendor/rustix/src/backend/linux_raw/time/syscalls.rs | 257 | ||||
| -rw-r--r-- | vendor/rustix/src/backend/linux_raw/time/types.rs | 100 | 
3 files changed, 360 insertions, 0 deletions
diff --git a/vendor/rustix/src/backend/linux_raw/time/mod.rs b/vendor/rustix/src/backend/linux_raw/time/mod.rs new file mode 100644 index 0000000..c42592c --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/time/mod.rs @@ -0,0 +1,3 @@ +#[cfg(any(feature = "time", target_arch = "x86"))] +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/time/syscalls.rs b/vendor/rustix/src/backend/linux_raw/time/syscalls.rs new file mode 100644 index 0000000..d20bcfa --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/time/syscalls.rs @@ -0,0 +1,257 @@ +//! linux_raw syscalls supporting `rustix::time`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] + +use crate::backend::conv::{ret, ret_infallible}; +use crate::clockid::ClockId; +use crate::io; +use crate::timespec::Timespec; +use core::mem::MaybeUninit; +#[cfg(all(feature = "time", target_pointer_width = "32"))] +use linux_raw_sys::general::itimerspec as __kernel_old_itimerspec; +#[cfg(target_pointer_width = "32")] +use linux_raw_sys::general::timespec as __kernel_old_timespec; +#[cfg(feature = "time")] +use { +    crate::backend::conv::{by_ref, ret_owned_fd}, +    crate::fd::BorrowedFd, +    crate::fd::OwnedFd, +    crate::time::{Itimerspec, TimerfdClockId, TimerfdFlags, TimerfdTimerFlags}, +}; + +// `clock_gettime` has special optimizations via the vDSO. +#[cfg(feature = "time")] +pub(crate) use crate::backend::vdso_wrappers::{clock_gettime, clock_gettime_dynamic}; + +#[inline] +pub(crate) fn clock_getres(which_clock: ClockId) -> Timespec { +    #[cfg(target_pointer_width = "32")] +    unsafe { +        let mut result = MaybeUninit::<Timespec>::uninit(); +        if let Err(err) = ret(syscall!(__NR_clock_getres_time64, which_clock, &mut result)) { +            // See the comments in `rustix_clock_gettime_via_syscall` about +            // emulation. +            debug_assert_eq!(err, io::Errno::NOSYS); +            clock_getres_old(which_clock, &mut result); +        } +        result.assume_init() +    } +    #[cfg(target_pointer_width = "64")] +    unsafe { +        let mut result = MaybeUninit::<Timespec>::uninit(); +        ret_infallible(syscall!(__NR_clock_getres, which_clock, &mut result)); +        result.assume_init() +    } +} + +#[cfg(target_pointer_width = "32")] +unsafe fn clock_getres_old(which_clock: ClockId, result: &mut MaybeUninit<Timespec>) { +    let mut old_result = MaybeUninit::<__kernel_old_timespec>::uninit(); +    ret_infallible(syscall!(__NR_clock_getres, which_clock, &mut old_result)); +    let old_result = old_result.assume_init(); +    result.write(Timespec { +        tv_sec: old_result.tv_sec.into(), +        tv_nsec: old_result.tv_nsec.into(), +    }); +} + +#[cfg(feature = "time")] +#[inline] +pub(crate) fn clock_settime(which_clock: ClockId, timespec: Timespec) -> io::Result<()> { +    // `clock_settime64` was introduced in Linux 5.1. The old `clock_settime` +    // syscall is not y2038-compatible on 32-bit architectures. +    #[cfg(target_pointer_width = "32")] +    unsafe { +        match ret(syscall_readonly!( +            __NR_clock_settime64, +            which_clock, +            by_ref(×pec) +        )) { +            Err(io::Errno::NOSYS) => clock_settime_old(which_clock, timespec), +            otherwise => otherwise, +        } +    } +    #[cfg(target_pointer_width = "64")] +    unsafe { +        ret(syscall_readonly!( +            __NR_clock_settime, +            which_clock, +            by_ref(×pec) +        )) +    } +} + +#[cfg(feature = "time")] +#[cfg(target_pointer_width = "32")] +unsafe fn clock_settime_old(which_clock: ClockId, timespec: Timespec) -> io::Result<()> { +    let old_timespec = __kernel_old_timespec { +        tv_sec: timespec +            .tv_sec +            .try_into() +            .map_err(|_| io::Errno::OVERFLOW)?, +        tv_nsec: timespec.tv_nsec as _, +    }; +    ret(syscall_readonly!( +        __NR_clock_settime, +        which_clock, +        by_ref(&old_timespec) +    )) +} + +#[cfg(feature = "time")] +#[inline] +pub(crate) fn timerfd_create(clockid: TimerfdClockId, flags: TimerfdFlags) -> io::Result<OwnedFd> { +    unsafe { ret_owned_fd(syscall_readonly!(__NR_timerfd_create, clockid, flags)) } +} + +#[cfg(feature = "time")] +#[inline] +pub(crate) fn timerfd_settime( +    fd: BorrowedFd<'_>, +    flags: TimerfdTimerFlags, +    new_value: &Itimerspec, +) -> io::Result<Itimerspec> { +    let mut result = MaybeUninit::<Itimerspec>::uninit(); + +    #[cfg(target_pointer_width = "64")] +    unsafe { +        ret(syscall!( +            __NR_timerfd_settime, +            fd, +            flags, +            by_ref(new_value), +            &mut result +        ))?; +        Ok(result.assume_init()) +    } + +    #[cfg(target_pointer_width = "32")] +    unsafe { +        ret(syscall!( +            __NR_timerfd_settime64, +            fd, +            flags, +            by_ref(new_value), +            &mut result +        )) +        .or_else(|err| { +            // See the comments in `rustix_clock_gettime_via_syscall` about +            // emulation. +            if err == io::Errno::NOSYS { +                timerfd_settime_old(fd, flags, new_value, &mut result) +            } else { +                Err(err) +            } +        })?; +        Ok(result.assume_init()) +    } +} + +#[cfg(feature = "time")] +#[cfg(target_pointer_width = "32")] +unsafe fn timerfd_settime_old( +    fd: BorrowedFd<'_>, +    flags: TimerfdTimerFlags, +    new_value: &Itimerspec, +    result: &mut MaybeUninit<Itimerspec>, +) -> io::Result<()> { +    let mut old_result = MaybeUninit::<__kernel_old_itimerspec>::uninit(); + +    // Convert `new_value` to the old `__kernel_old_itimerspec` format. +    let old_new_value = __kernel_old_itimerspec { +        it_interval: __kernel_old_timespec { +            tv_sec: new_value +                .it_interval +                .tv_sec +                .try_into() +                .map_err(|_| io::Errno::OVERFLOW)?, +            tv_nsec: new_value +                .it_interval +                .tv_nsec +                .try_into() +                .map_err(|_| io::Errno::INVAL)?, +        }, +        it_value: __kernel_old_timespec { +            tv_sec: new_value +                .it_value +                .tv_sec +                .try_into() +                .map_err(|_| io::Errno::OVERFLOW)?, +            tv_nsec: new_value +                .it_value +                .tv_nsec +                .try_into() +                .map_err(|_| io::Errno::INVAL)?, +        }, +    }; +    ret(syscall!( +        __NR_timerfd_settime, +        fd, +        flags, +        by_ref(&old_new_value), +        &mut old_result +    ))?; +    let old_result = old_result.assume_init(); +    result.write(Itimerspec { +        it_interval: Timespec { +            tv_sec: old_result.it_interval.tv_sec.into(), +            tv_nsec: old_result.it_interval.tv_nsec.into(), +        }, +        it_value: Timespec { +            tv_sec: old_result.it_value.tv_sec.into(), +            tv_nsec: old_result.it_value.tv_nsec.into(), +        }, +    }); +    Ok(()) +} + +#[cfg(feature = "time")] +#[inline] +pub(crate) fn timerfd_gettime(fd: BorrowedFd<'_>) -> io::Result<Itimerspec> { +    let mut result = MaybeUninit::<Itimerspec>::uninit(); + +    #[cfg(target_pointer_width = "64")] +    unsafe { +        ret(syscall!(__NR_timerfd_gettime, fd, &mut result))?; +        Ok(result.assume_init()) +    } + +    #[cfg(target_pointer_width = "32")] +    unsafe { +        ret(syscall!(__NR_timerfd_gettime64, fd, &mut result)).or_else(|err| { +            // See the comments in `rustix_clock_gettime_via_syscall` about +            // emulation. +            if err == io::Errno::NOSYS { +                timerfd_gettime_old(fd, &mut result) +            } else { +                Err(err) +            } +        })?; +        Ok(result.assume_init()) +    } +} + +#[cfg(feature = "time")] +#[cfg(target_pointer_width = "32")] +unsafe fn timerfd_gettime_old( +    fd: BorrowedFd<'_>, +    result: &mut MaybeUninit<Itimerspec>, +) -> io::Result<()> { +    let mut old_result = MaybeUninit::<__kernel_old_itimerspec>::uninit(); +    ret(syscall!(__NR_timerfd_gettime, fd, &mut old_result))?; +    let old_result = old_result.assume_init(); +    result.write(Itimerspec { +        it_interval: Timespec { +            tv_sec: old_result.it_interval.tv_sec.into(), +            tv_nsec: old_result.it_interval.tv_nsec.into(), +        }, +        it_value: Timespec { +            tv_sec: old_result.it_value.tv_sec.into(), +            tv_nsec: old_result.it_value.tv_nsec.into(), +        }, +    }); +    Ok(()) +} diff --git a/vendor/rustix/src/backend/linux_raw/time/types.rs b/vendor/rustix/src/backend/linux_raw/time/types.rs new file mode 100644 index 0000000..c26812c --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/time/types.rs @@ -0,0 +1,100 @@ +use crate::backend::c; +use bitflags::bitflags; + +/// `struct itimerspec` for use with [`timerfd_gettime`] and +/// [`timerfd_settime`]. +/// +/// [`timerfd_gettime`]: crate::time::timerfd_gettime +/// [`timerfd_settime`]: crate::time::timerfd_settime +pub type Itimerspec = linux_raw_sys::general::__kernel_itimerspec; + +bitflags! { +    /// `TFD_*` flags for use with [`timerfd_create`]. +    /// +    /// [`timerfd_create`]: crate::time::timerfd_create +    #[repr(transparent)] +    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] +    pub struct TimerfdFlags: 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> +        const _ = !0; +    } +} + +bitflags! { +    /// `TFD_TIMER_*` flags for use with [`timerfd_settime`]. +    /// +    /// [`timerfd_settime`]: crate::time::timerfd_settime +    #[repr(transparent)] +    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] +    pub struct TimerfdTimerFlags: 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> +        const _ = !0; +    } +} + +/// `CLOCK_*` constants for use with [`timerfd_create`]. +/// +/// [`timerfd_create`]: crate::time::timerfd_create +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +#[repr(u32)] +#[non_exhaustive] +pub enum TimerfdClockId { +    /// `CLOCK_REALTIME`—A clock that tells the “real” time. +    /// +    /// This is a clock that tells the amount of time elapsed since the Unix +    /// epoch, 1970-01-01T00:00:00Z. The clock is externally settable, so it is +    /// not monotonic. Successive reads may see decreasing times, so it isn't +    /// reliable for measuring durations. +    #[doc(alias = "CLOCK_REALTIME")] +    Realtime = linux_raw_sys::general::CLOCK_REALTIME, + +    /// `CLOCK_MONOTONIC`—A clock that tells an abstract time. +    /// +    /// Unlike `Realtime`, this clock is not based on a fixed known epoch, so +    /// individual times aren't meaningful. However, since it isn't settable, +    /// it is reliable for measuring durations. +    /// +    /// This clock does not advance while the system is suspended; see +    /// `Boottime` for a clock that does. +    #[doc(alias = "CLOCK_MONOTONIC")] +    Monotonic = linux_raw_sys::general::CLOCK_MONOTONIC, + +    /// `CLOCK_BOOTTIME`—Like `Monotonic`, but advances while suspended. +    /// +    /// This clock is similar to `Monotonic`, but does advance while the system +    /// is suspended. +    #[doc(alias = "CLOCK_BOOTTIME")] +    Boottime = linux_raw_sys::general::CLOCK_BOOTTIME, + +    /// `CLOCK_REALTIME_ALARM`—Like `Realtime`, but wakes a suspended system. +    /// +    /// This clock is like `Realtime`, but can wake up a suspended system. +    /// +    /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. +    #[doc(alias = "CLOCK_REALTIME_ALARM")] +    RealtimeAlarm = linux_raw_sys::general::CLOCK_REALTIME_ALARM, + +    /// `CLOCK_BOOTTIME_ALARM`—Like `Boottime`, but wakes a suspended system. +    /// +    /// This clock is like `Boottime`, but can wake up a suspended system. +    /// +    /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. +    #[doc(alias = "CLOCK_BOOTTIME_ALARM")] +    BoottimeAlarm = linux_raw_sys::general::CLOCK_BOOTTIME_ALARM, +}  | 
