diff options
Diffstat (limited to 'vendor/rustix/src/backend/libc/time')
| -rw-r--r-- | vendor/rustix/src/backend/libc/time/mod.rs | 3 | ||||
| -rw-r--r-- | vendor/rustix/src/backend/libc/time/syscalls.rs | 452 | ||||
| -rw-r--r-- | vendor/rustix/src/backend/libc/time/types.rs | 177 | 
3 files changed, 632 insertions, 0 deletions
diff --git a/vendor/rustix/src/backend/libc/time/mod.rs b/vendor/rustix/src/backend/libc/time/mod.rs new file mode 100644 index 0000000..bff7fd5 --- /dev/null +++ b/vendor/rustix/src/backend/libc/time/mod.rs @@ -0,0 +1,3 @@ +#[cfg(not(windows))] +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/time/syscalls.rs b/vendor/rustix/src/backend/libc/time/syscalls.rs new file mode 100644 index 0000000..6b1c9fd --- /dev/null +++ b/vendor/rustix/src/backend/libc/time/syscalls.rs @@ -0,0 +1,452 @@ +//! libc syscalls supporting `rustix::time`. + +use crate::backend::c; +use crate::backend::conv::ret; +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(feature = "time")] +#[cfg(any(all(target_env = "gnu", fix_y2038), not(fix_y2038)))] +use crate::backend::time::types::LibcItimerspec; +#[cfg(not(target_os = "wasi"))] +use crate::clockid::{ClockId, DynamicClockId}; +use crate::io; +#[cfg(all(target_env = "gnu", fix_y2038))] +use crate::timespec::LibcTimespec; +use crate::timespec::Timespec; +use core::mem::MaybeUninit; +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(feature = "time")] +use { +    crate::backend::conv::{borrowed_fd, ret_owned_fd}, +    crate::fd::{BorrowedFd, OwnedFd}, +    crate::time::{Itimerspec, TimerfdClockId, TimerfdFlags, TimerfdTimerFlags}, +}; + +#[cfg(all(target_env = "gnu", fix_y2038))] +weak!(fn __clock_gettime64(c::clockid_t, *mut LibcTimespec) -> c::c_int); +#[cfg(all(target_env = "gnu", fix_y2038))] +weak!(fn __clock_settime64(c::clockid_t, *const LibcTimespec) -> c::c_int); +#[cfg(all(target_env = "gnu", fix_y2038))] +weak!(fn __clock_getres64(c::clockid_t, *mut LibcTimespec) -> c::c_int); +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(all(target_env = "gnu", fix_y2038))] +#[cfg(feature = "time")] +weak!(fn __timerfd_gettime64(c::c_int, *mut LibcItimerspec) -> c::c_int); +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(all(target_env = "gnu", fix_y2038))] +#[cfg(feature = "time")] +weak!(fn __timerfd_settime64(c::c_int, c::c_int, *const LibcItimerspec, *mut LibcItimerspec) -> c::c_int); + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +#[inline] +#[must_use] +pub(crate) fn clock_getres(id: ClockId) -> Timespec { +    // Old 32-bit version: libc has `clock_getres` but it is not y2038 safe by +    // default. But there may be a `__clock_getres64` we can use. +    #[cfg(fix_y2038)] +    { +        #[cfg(target_env = "gnu")] +        if let Some(libc_clock_getres) = __clock_getres64.get() { +            let mut timespec = MaybeUninit::<LibcTimespec>::uninit(); +            unsafe { +                ret(libc_clock_getres(id as c::clockid_t, timespec.as_mut_ptr())).unwrap(); +                return timespec.assume_init().into(); +            } +        } + +        clock_getres_old(id) +    } + +    // Main version: libc is y2038 safe and has `clock_getres`. +    #[cfg(not(fix_y2038))] +    unsafe { +        let mut timespec = MaybeUninit::<Timespec>::uninit(); +        let _ = c::clock_getres(id as c::clockid_t, timespec.as_mut_ptr()); +        timespec.assume_init() +    } +} + +#[cfg(fix_y2038)] +#[must_use] +fn clock_getres_old(id: ClockId) -> Timespec { +    let mut old_timespec = MaybeUninit::<c::timespec>::uninit(); + +    let old_timespec = unsafe { +        ret(c::clock_getres( +            id as c::clockid_t, +            old_timespec.as_mut_ptr(), +        )) +        .unwrap(); +        old_timespec.assume_init() +    }; + +    Timespec { +        tv_sec: old_timespec.tv_sec.into(), +        tv_nsec: old_timespec.tv_nsec.into(), +    } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +#[must_use] +pub(crate) fn clock_gettime(id: ClockId) -> Timespec { +    // Old 32-bit version: libc has `clock_gettime` but it is not y2038 safe by +    // default. But there may be a `__clock_gettime64` we can use. +    #[cfg(fix_y2038)] +    { +        #[cfg(target_env = "gnu")] +        if let Some(libc_clock_gettime) = __clock_gettime64.get() { +            let mut timespec = MaybeUninit::<LibcTimespec>::uninit(); +            unsafe { +                ret(libc_clock_gettime( +                    id as c::clockid_t, +                    timespec.as_mut_ptr(), +                )) +                .unwrap(); +                return timespec.assume_init().into(); +            } +        } + +        clock_gettime_old(id) +    } + +    // Use `.unwrap()` here because `clock_getres` can fail if the clock itself +    // overflows a number of seconds, but if that happens, the monotonic clocks +    // can't maintain their invariants, or the realtime clocks aren't properly +    // configured. +    #[cfg(not(fix_y2038))] +    unsafe { +        let mut timespec = MaybeUninit::<Timespec>::uninit(); +        ret(c::clock_gettime(id as c::clockid_t, timespec.as_mut_ptr())).unwrap(); +        timespec.assume_init() +    } +} + +#[cfg(fix_y2038)] +#[must_use] +fn clock_gettime_old(id: ClockId) -> Timespec { +    let mut old_timespec = MaybeUninit::<c::timespec>::uninit(); + +    let old_timespec = unsafe { +        ret(c::clock_gettime( +            id as c::clockid_t, +            old_timespec.as_mut_ptr(), +        )) +        .unwrap(); +        old_timespec.assume_init() +    }; + +    Timespec { +        tv_sec: old_timespec.tv_sec.into(), +        tv_nsec: old_timespec.tv_nsec.into(), +    } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +pub(crate) fn clock_gettime_dynamic(id: DynamicClockId<'_>) -> io::Result<Timespec> { +    let id: c::clockid_t = match id { +        DynamicClockId::Known(id) => id as c::clockid_t, + +        #[cfg(linux_kernel)] +        DynamicClockId::Dynamic(fd) => { +            use crate::fd::AsRawFd; +            const CLOCKFD: i32 = 3; +            (!fd.as_raw_fd() << 3) | CLOCKFD +        } + +        #[cfg(not(linux_kernel))] +        DynamicClockId::Dynamic(_fd) => { +            // Dynamic clocks are not supported on this platform. +            return Err(io::Errno::INVAL); +        } + +        #[cfg(linux_kernel)] +        DynamicClockId::RealtimeAlarm => c::CLOCK_REALTIME_ALARM, + +        #[cfg(linux_kernel)] +        DynamicClockId::Tai => c::CLOCK_TAI, + +        #[cfg(any( +            freebsdlike, +            linux_kernel, +            target_os = "fuchsia", +            target_os = "openbsd" +        ))] +        DynamicClockId::Boottime => c::CLOCK_BOOTTIME, + +        #[cfg(any(linux_kernel, target_os = "fuchsia"))] +        DynamicClockId::BoottimeAlarm => c::CLOCK_BOOTTIME_ALARM, +    }; + +    // Old 32-bit version: libc has `clock_gettime` but it is not y2038 +    // safe by default. But there may be a `__clock_gettime64` we can use. +    #[cfg(fix_y2038)] +    { +        #[cfg(target_env = "gnu")] +        if let Some(libc_clock_gettime) = __clock_gettime64.get() { +            let mut timespec = MaybeUninit::<LibcTimespec>::uninit(); +            unsafe { +                ret(libc_clock_gettime( +                    id as c::clockid_t, +                    timespec.as_mut_ptr(), +                ))?; + +                return Ok(timespec.assume_init().into()); +            } +        } + +        clock_gettime_dynamic_old(id) +    } + +    // Main version: libc is y2038 safe and has `clock_gettime`. +    #[cfg(not(fix_y2038))] +    unsafe { +        let mut timespec = MaybeUninit::<Timespec>::uninit(); + +        ret(c::clock_gettime(id as c::clockid_t, timespec.as_mut_ptr()))?; + +        Ok(timespec.assume_init()) +    } +} + +#[cfg(fix_y2038)] +#[inline] +fn clock_gettime_dynamic_old(id: c::clockid_t) -> io::Result<Timespec> { +    let mut old_timespec = MaybeUninit::<c::timespec>::uninit(); + +    let old_timespec = unsafe { +        ret(c::clock_gettime( +            id as c::clockid_t, +            old_timespec.as_mut_ptr(), +        ))?; + +        old_timespec.assume_init() +    }; + +    Ok(Timespec { +        tv_sec: old_timespec.tv_sec.into(), +        tv_nsec: old_timespec.tv_nsec.into(), +    }) +} + +#[cfg(not(any( +    target_os = "redox", +    target_os = "wasi", +    all(apple, not(target_os = "macos")) +)))] +#[inline] +pub(crate) fn clock_settime(id: ClockId, timespec: Timespec) -> io::Result<()> { +    // Old 32-bit version: libc has `clock_gettime` but it is not y2038 safe by +    // default. But there may be a `__clock_settime64` we can use. +    #[cfg(fix_y2038)] +    { +        #[cfg(target_env = "gnu")] +        if let Some(libc_clock_settime) = __clock_settime64.get() { +            unsafe { +                let mut new_timespec = core::mem::zeroed::<LibcTimespec>(); +                new_timespec.tv_sec = timespec.tv_sec; +                new_timespec.tv_nsec = timespec.tv_nsec as _; +                return ret(libc_clock_settime(id as c::clockid_t, &new_timespec)); +            } +        } + +        clock_settime_old(id, timespec) +    } + +    // Main version: libc is y2038 safe and has `clock_settime`. +    #[cfg(not(fix_y2038))] +    unsafe { +        ret(c::clock_settime(id as c::clockid_t, ×pec)) +    } +} + +#[cfg(not(any( +    target_os = "redox", +    target_os = "wasi", +    all(apple, not(target_os = "macos")) +)))] +#[cfg(fix_y2038)] +fn clock_settime_old(id: ClockId, timespec: Timespec) -> io::Result<()> { +    let old_timespec = c::timespec { +        tv_sec: timespec +            .tv_sec +            .try_into() +            .map_err(|_| io::Errno::OVERFLOW)?, +        tv_nsec: timespec.tv_nsec as _, +    }; + +    unsafe { ret(c::clock_settime(id as c::clockid_t, &old_timespec)) } +} + +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(feature = "time")] +pub(crate) fn timerfd_create(id: TimerfdClockId, flags: TimerfdFlags) -> io::Result<OwnedFd> { +    unsafe { ret_owned_fd(c::timerfd_create(id as c::clockid_t, bitflags_bits!(flags))) } +} + +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(feature = "time")] +pub(crate) fn timerfd_settime( +    fd: BorrowedFd<'_>, +    flags: TimerfdTimerFlags, +    new_value: &Itimerspec, +) -> io::Result<Itimerspec> { +    // Old 32-bit version: libc has `timerfd_settime` but it is not y2038 safe +    // by default. But there may be a `__timerfd_settime64` we can use. +    #[cfg(fix_y2038)] +    { +        #[cfg(target_env = "gnu")] +        if let Some(libc_timerfd_settime) = __timerfd_settime64.get() { +            let mut result = MaybeUninit::<LibcItimerspec>::uninit(); +            unsafe { +                ret(libc_timerfd_settime( +                    borrowed_fd(fd), +                    bitflags_bits!(flags), +                    &new_value.clone().into(), +                    result.as_mut_ptr(), +                ))?; +                return Ok(result.assume_init().into()); +            } +        } + +        timerfd_settime_old(fd, flags, new_value) +    } + +    #[cfg(not(fix_y2038))] +    unsafe { +        let mut result = MaybeUninit::<LibcItimerspec>::uninit(); +        ret(c::timerfd_settime( +            borrowed_fd(fd), +            bitflags_bits!(flags), +            new_value, +            result.as_mut_ptr(), +        ))?; +        Ok(result.assume_init()) +    } +} + +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(fix_y2038)] +#[cfg(feature = "time")] +fn timerfd_settime_old( +    fd: BorrowedFd<'_>, +    flags: TimerfdTimerFlags, +    new_value: &Itimerspec, +) -> io::Result<Itimerspec> { +    let mut old_result = MaybeUninit::<c::itimerspec>::uninit(); + +    // Convert `new_value` to the old `itimerspec` format. +    let old_new_value = c::itimerspec { +        it_interval: c::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: c::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)?, +        }, +    }; + +    let old_result = unsafe { +        ret(c::timerfd_settime( +            borrowed_fd(fd), +            bitflags_bits!(flags), +            &old_new_value, +            old_result.as_mut_ptr(), +        ))?; +        old_result.assume_init() +    }; + +    Ok(Itimerspec { +        it_interval: Timespec { +            tv_sec: old_result +                .it_interval +                .tv_sec +                .try_into() +                .map_err(|_| io::Errno::OVERFLOW)?, +            tv_nsec: old_result.it_interval.tv_nsec as _, +        }, +        it_value: Timespec { +            tv_sec: old_result +                .it_interval +                .tv_sec +                .try_into() +                .map_err(|_| io::Errno::OVERFLOW)?, +            tv_nsec: old_result.it_interval.tv_nsec as _, +        }, +    }) +} + +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(feature = "time")] +pub(crate) fn timerfd_gettime(fd: BorrowedFd<'_>) -> io::Result<Itimerspec> { +    // Old 32-bit version: libc has `timerfd_gettime` but it is not y2038 safe +    // by default. But there may be a `__timerfd_gettime64` we can use. +    #[cfg(fix_y2038)] +    { +        #[cfg(target_env = "gnu")] +        if let Some(libc_timerfd_gettime) = __timerfd_gettime64.get() { +            let mut result = MaybeUninit::<LibcItimerspec>::uninit(); +            unsafe { +                ret(libc_timerfd_gettime(borrowed_fd(fd), result.as_mut_ptr()))?; +                return Ok(result.assume_init().into()); +            } +        } + +        timerfd_gettime_old(fd) +    } + +    #[cfg(not(fix_y2038))] +    unsafe { +        let mut result = MaybeUninit::<LibcItimerspec>::uninit(); +        ret(c::timerfd_gettime(borrowed_fd(fd), result.as_mut_ptr()))?; +        Ok(result.assume_init()) +    } +} + +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(fix_y2038)] +#[cfg(feature = "time")] +fn timerfd_gettime_old(fd: BorrowedFd<'_>) -> io::Result<Itimerspec> { +    let mut old_result = MaybeUninit::<c::itimerspec>::uninit(); + +    let old_result = unsafe { +        ret(c::timerfd_gettime(borrowed_fd(fd), old_result.as_mut_ptr()))?; +        old_result.assume_init() +    }; + +    Ok(Itimerspec { +        it_interval: Timespec { +            tv_sec: old_result +                .it_interval +                .tv_sec +                .try_into() +                .map_err(|_| io::Errno::OVERFLOW)?, +            tv_nsec: old_result.it_interval.tv_nsec as _, +        }, +        it_value: Timespec { +            tv_sec: old_result +                .it_interval +                .tv_sec +                .try_into() +                .map_err(|_| io::Errno::OVERFLOW)?, +            tv_nsec: old_result.it_interval.tv_nsec as _, +        }, +    }) +} diff --git a/vendor/rustix/src/backend/libc/time/types.rs b/vendor/rustix/src/backend/libc/time/types.rs new file mode 100644 index 0000000..5254c6b --- /dev/null +++ b/vendor/rustix/src/backend/libc/time/types.rs @@ -0,0 +1,177 @@ +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +use crate::backend::c; +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(fix_y2038)] +use crate::timespec::LibcTimespec; +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(fix_y2038)] +use crate::timespec::Timespec; +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +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 +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(not(fix_y2038))] +pub type Itimerspec = c::itimerspec; + +/// `struct itimerspec` for use with [`timerfd_gettime`] and +/// [`timerfd_settime`]. +/// +/// [`timerfd_gettime`]: crate::time::timerfd_gettime +/// [`timerfd_settime`]: crate::time::timerfd_settime +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(fix_y2038)] +#[repr(C)] +#[derive(Debug, Clone)] +pub struct Itimerspec { +    /// The interval of an interval timer. +    pub it_interval: Timespec, +    /// Time remaining in the current interval. +    pub it_value: Timespec, +} + +/// On most platforms, `LibcItimerspec` is just `Itimerspec`. +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(not(fix_y2038))] +pub(crate) type LibcItimerspec = Itimerspec; + +/// On 32-bit glibc platforms, `LibcTimespec` differs from `Timespec`, so we +/// define our own struct, with bidirectional `From` impls. +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(fix_y2038)] +#[repr(C)] +#[derive(Debug, Clone)] +pub(crate) struct LibcItimerspec { +    pub it_interval: LibcTimespec, +    pub it_value: LibcTimespec, +} + +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(fix_y2038)] +impl From<LibcItimerspec> for Itimerspec { +    #[inline] +    fn from(t: LibcItimerspec) -> Self { +        Self { +            it_interval: t.it_interval.into(), +            it_value: t.it_value.into(), +        } +    } +} + +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[cfg(fix_y2038)] +impl From<Itimerspec> for LibcItimerspec { +    #[inline] +    fn from(t: Itimerspec) -> Self { +        Self { +            it_interval: t.it_interval.into(), +            it_value: t.it_value.into(), +        } +    } +} + +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +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: 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> +        const _ = !0; +    } +} + +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +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: 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> +        const _ = !0; +    } +} + +/// `CLOCK_*` constants for use with [`timerfd_create`]. +/// +/// [`timerfd_create`]: crate::time::timerfd_create +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[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 = bitcast!(c::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 = 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. +    /// +    /// 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. +    /// +    /// 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), +} + +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[test] +fn test_types() { +    assert_eq_size!(TimerfdFlags, c::c_int); +    assert_eq_size!(TimerfdTimerFlags, c::c_int); +}  | 
