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