rustix/backend/libc/time/
types.rs

1#[cfg(any(linux_kernel, target_os = "fuchsia"))]
2use crate::backend::c;
3#[cfg(any(linux_kernel, target_os = "fuchsia"))]
4use crate::time::Itimerspec;
5#[cfg(any(linux_kernel, target_os = "fuchsia"))]
6#[cfg(fix_y2038)]
7use crate::timespec::LibcTimespec;
8#[cfg(any(linux_kernel, target_os = "fuchsia"))]
9use bitflags::bitflags;
10
11/// On most platforms, `LibcItimerspec` is just `Itimerspec`.
12#[cfg(any(linux_kernel, target_os = "fuchsia"))]
13#[cfg(not(fix_y2038))]
14pub(crate) type LibcItimerspec = Itimerspec;
15
16/// On 32-bit glibc platforms, `LibcTimespec` differs from `Timespec`, so we
17/// define our own struct, with bidirectional `From` impls.
18#[cfg(any(linux_kernel, target_os = "fuchsia"))]
19#[cfg(fix_y2038)]
20#[repr(C)]
21#[derive(Debug, Clone)]
22pub(crate) struct LibcItimerspec {
23    pub it_interval: LibcTimespec,
24    pub it_value: LibcTimespec,
25}
26
27#[cfg(any(linux_kernel, target_os = "fuchsia"))]
28#[cfg(fix_y2038)]
29impl From<LibcItimerspec> for Itimerspec {
30    #[inline]
31    fn from(t: LibcItimerspec) -> Self {
32        Self {
33            it_interval: t.it_interval.into(),
34            it_value: t.it_value.into(),
35        }
36    }
37}
38
39#[cfg(any(linux_kernel, target_os = "fuchsia"))]
40#[cfg(fix_y2038)]
41impl From<Itimerspec> for LibcItimerspec {
42    #[inline]
43    fn from(t: Itimerspec) -> Self {
44        Self {
45            it_interval: t.it_interval.into(),
46            it_value: t.it_value.into(),
47        }
48    }
49}
50
51#[cfg(any(linux_kernel, target_os = "fuchsia"))]
52#[cfg(not(fix_y2038))]
53pub(crate) fn as_libc_itimerspec_ptr(itimerspec: &Itimerspec) -> *const c::itimerspec {
54    #[cfg(test)]
55    {
56        assert_eq_size!(Itimerspec, c::itimerspec);
57    }
58    crate::utils::as_ptr(itimerspec).cast::<c::itimerspec>()
59}
60
61#[cfg(any(linux_kernel, target_os = "fuchsia"))]
62#[cfg(not(fix_y2038))]
63pub(crate) fn as_libc_itimerspec_mut_ptr(
64    itimerspec: &mut core::mem::MaybeUninit<Itimerspec>,
65) -> *mut c::itimerspec {
66    #[cfg(test)]
67    {
68        assert_eq_size!(Itimerspec, c::itimerspec);
69    }
70    itimerspec.as_mut_ptr().cast::<c::itimerspec>()
71}
72
73#[cfg(any(linux_kernel, target_os = "fuchsia"))]
74bitflags! {
75    /// `TFD_*` flags for use with [`timerfd_create`].
76    ///
77    /// [`timerfd_create`]: crate::time::timerfd_create
78    #[repr(transparent)]
79    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
80    pub struct TimerfdFlags: u32 {
81        /// `TFD_NONBLOCK`
82        #[doc(alias = "TFD_NONBLOCK")]
83        const NONBLOCK = bitcast!(c::TFD_NONBLOCK);
84
85        /// `TFD_CLOEXEC`
86        #[doc(alias = "TFD_CLOEXEC")]
87        const CLOEXEC = bitcast!(c::TFD_CLOEXEC);
88
89        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
90        const _ = !0;
91    }
92}
93
94#[cfg(any(linux_kernel, target_os = "fuchsia"))]
95bitflags! {
96    /// `TFD_TIMER_*` flags for use with [`timerfd_settime`].
97    ///
98    /// [`timerfd_settime`]: crate::time::timerfd_settime
99    #[repr(transparent)]
100    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
101    pub struct TimerfdTimerFlags: u32 {
102        /// `TFD_TIMER_ABSTIME`
103        #[doc(alias = "TFD_TIMER_ABSTIME")]
104        const ABSTIME = bitcast!(c::TFD_TIMER_ABSTIME);
105
106        /// `TFD_TIMER_CANCEL_ON_SET`
107        #[cfg(linux_kernel)]
108        #[doc(alias = "TFD_TIMER_CANCEL_ON_SET")]
109        const CANCEL_ON_SET = bitcast!(c::TFD_TIMER_CANCEL_ON_SET);
110
111        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
112        const _ = !0;
113    }
114}
115
116/// `CLOCK_*` constants for use with [`timerfd_create`].
117///
118/// [`timerfd_create`]: crate::time::timerfd_create
119#[cfg(any(linux_kernel, target_os = "fuchsia"))]
120#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
121#[repr(u32)]
122#[non_exhaustive]
123pub enum TimerfdClockId {
124    /// `CLOCK_REALTIME`—A clock that tells the “real” time.
125    ///
126    /// This is a clock that tells the amount of time elapsed since the Unix
127    /// epoch, 1970-01-01T00:00:00Z. The clock is externally settable, so it is
128    /// not monotonic. Successive reads may see decreasing times, so it isn't
129    /// reliable for measuring durations.
130    #[doc(alias = "CLOCK_REALTIME")]
131    Realtime = bitcast!(c::CLOCK_REALTIME),
132
133    /// `CLOCK_MONOTONIC`—A clock that tells an abstract time.
134    ///
135    /// Unlike `Realtime`, this clock is not based on a fixed known epoch, so
136    /// individual times aren't meaningful. However, since it isn't settable,
137    /// it is reliable for measuring durations.
138    ///
139    /// This clock does not advance while the system is suspended; see
140    /// `Boottime` for a clock that does.
141    #[doc(alias = "CLOCK_MONOTONIC")]
142    Monotonic = bitcast!(c::CLOCK_MONOTONIC),
143
144    /// `CLOCK_BOOTTIME`—Like `Monotonic`, but advances while suspended.
145    ///
146    /// This clock is similar to `Monotonic`, but does advance while the system
147    /// is suspended.
148    #[doc(alias = "CLOCK_BOOTTIME")]
149    Boottime = bitcast!(c::CLOCK_BOOTTIME),
150
151    /// `CLOCK_REALTIME_ALARM`—Like `Realtime`, but wakes a suspended system.
152    ///
153    /// This clock is like `Realtime`, but can wake up a suspended system.
154    ///
155    /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability.
156    #[doc(alias = "CLOCK_REALTIME_ALARM")]
157    RealtimeAlarm = bitcast!(c::CLOCK_REALTIME_ALARM),
158
159    /// `CLOCK_BOOTTIME_ALARM`—Like `Boottime`, but wakes a suspended system.
160    ///
161    /// This clock is like `Boottime`, but can wake up a suspended system.
162    ///
163    /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability.
164    #[doc(alias = "CLOCK_BOOTTIME_ALARM")]
165    BoottimeAlarm = bitcast!(c::CLOCK_BOOTTIME_ALARM),
166}
167
168#[cfg(test)]
169mod tests {
170    #[allow(unused_imports)]
171    use super::*;
172
173    #[cfg(any(linux_kernel, target_os = "fuchsia"))]
174    #[test]
175    fn test_types() {
176        assert_eq_size!(TimerfdFlags, c::c_int);
177        assert_eq_size!(TimerfdTimerFlags, c::c_int);
178    }
179}