Skip to content

Commit

Permalink
Support the timerfd API on FreeBSD.
Browse files Browse the repository at this point in the history
FreeBSD has recently added support for Linux's timerfd API. Enable
rustix's timerfd API on FreeBSD as well.
  • Loading branch information
sunfishcode committed May 17, 2024
1 parent 07a80aa commit c638fea
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 29 deletions.
20 changes: 10 additions & 10 deletions src/backend/libc/time/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::backend::c;
use crate::backend::conv::ret;
#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
#[cfg(feature = "time")]
#[cfg(any(all(target_env = "gnu", fix_y2038), not(fix_y2038)))]
use crate::backend::time::types::LibcItimerspec;
Expand All @@ -13,7 +13,7 @@ use crate::io;
use crate::timespec::LibcTimespec;
use crate::timespec::Timespec;
use core::mem::MaybeUninit;
#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
#[cfg(feature = "time")]
use {
crate::backend::conv::{borrowed_fd, ret_owned_fd},
Expand All @@ -27,11 +27,11 @@ weak!(fn __clock_gettime64(c::clockid_t, *mut LibcTimespec) -> c::c_int);
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(any(linux_kernel, target_os = "freebsd", 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(any(linux_kernel, target_os = "freebsd", 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);
Expand Down Expand Up @@ -160,7 +160,7 @@ pub(crate) fn clock_gettime_dynamic(id: DynamicClockId<'_>) -> io::Result<Timesp
return Err(io::Errno::INVAL);
}

#[cfg(linux_kernel)]
#[cfg(any(linux_kernel, target_os = "fuchsia"))]
DynamicClockId::RealtimeAlarm => c::CLOCK_REALTIME_ALARM,

#[cfg(linux_kernel)]
Expand Down Expand Up @@ -278,13 +278,13 @@ fn clock_settime_old(id: ClockId, timespec: Timespec) -> io::Result<()> {
unsafe { ret(c::clock_settime(id as c::clockid_t, &old_timespec)) }
}

#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", 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(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
#[cfg(feature = "time")]
pub(crate) fn timerfd_settime(
fd: BorrowedFd<'_>,
Expand Down Expand Up @@ -325,7 +325,7 @@ pub(crate) fn timerfd_settime(
}
}

#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
#[cfg(fix_y2038)]
#[cfg(feature = "time")]
fn timerfd_settime_old(
Expand Down Expand Up @@ -393,7 +393,7 @@ fn timerfd_settime_old(
})
}

#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", 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
Expand All @@ -420,7 +420,7 @@ pub(crate) fn timerfd_gettime(fd: BorrowedFd<'_>) -> io::Result<Itimerspec> {
}
}

#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
#[cfg(fix_y2038)]
#[cfg(feature = "time")]
fn timerfd_gettime_old(fd: BorrowedFd<'_>) -> io::Result<Itimerspec> {
Expand Down
32 changes: 17 additions & 15 deletions src/backend/libc/time/types.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
use crate::backend::c;
#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
#[cfg(fix_y2038)]
use crate::timespec::LibcTimespec;
#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
#[cfg(fix_y2038)]
use crate::timespec::Timespec;
#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", 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(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
#[cfg(not(fix_y2038))]
pub type Itimerspec = c::itimerspec;

Expand All @@ -23,7 +23,7 @@ pub type Itimerspec = c::itimerspec;
///
/// [`timerfd_gettime`]: crate::time::timerfd_gettime
/// [`timerfd_settime`]: crate::time::timerfd_settime
#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
#[cfg(fix_y2038)]
#[repr(C)]
#[derive(Debug, Clone)]
Expand All @@ -35,13 +35,13 @@ pub struct Itimerspec {
}

/// On most platforms, `LibcItimerspec` is just `Itimerspec`.
#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", 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(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
#[cfg(fix_y2038)]
#[repr(C)]
#[derive(Debug, Clone)]
Expand All @@ -50,7 +50,7 @@ pub(crate) struct LibcItimerspec {
pub it_value: LibcTimespec,
}

#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
#[cfg(fix_y2038)]
impl From<LibcItimerspec> for Itimerspec {
#[inline]
Expand All @@ -62,7 +62,7 @@ impl From<LibcItimerspec> for Itimerspec {
}
}

#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
#[cfg(fix_y2038)]
impl From<Itimerspec> for LibcItimerspec {
#[inline]
Expand All @@ -74,7 +74,7 @@ impl From<Itimerspec> for LibcItimerspec {
}
}

#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
bitflags! {
/// `TFD_*` flags for use with [`timerfd_create`].
///
Expand All @@ -95,7 +95,7 @@ bitflags! {
}
}

#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
bitflags! {
/// `TFD_TIMER_*` flags for use with [`timerfd_settime`].
///
Expand All @@ -108,7 +108,7 @@ bitflags! {
const ABSTIME = bitcast!(c::TFD_TIMER_ABSTIME);

/// `TFD_TIMER_CANCEL_ON_SET`
#[cfg(linux_kernel)]
#[cfg(any(linux_kernel, target_os = "freebsd"))]
#[doc(alias = "TFD_TIMER_CANCEL_ON_SET")]
const CANCEL_ON_SET = bitcast!(c::TFD_TIMER_CANCEL_ON_SET);

Expand All @@ -120,7 +120,7 @@ bitflags! {
/// `CLOCK_*` constants for use with [`timerfd_create`].
///
/// [`timerfd_create`]: crate::time::timerfd_create
#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[repr(u32)]
#[non_exhaustive]
Expand Down Expand Up @@ -157,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.
#[cfg(linux_kernel)]
#[doc(alias = "CLOCK_REALTIME_ALARM")]
RealtimeAlarm = bitcast!(c::CLOCK_REALTIME_ALARM),

Expand All @@ -165,11 +166,12 @@ 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.
#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[doc(alias = "CLOCK_BOOTTIME_ALARM")]
BoottimeAlarm = bitcast!(c::CLOCK_BOOTTIME_ALARM),
}

#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
#[test]
fn test_types() {
assert_eq_size!(TimerfdFlags, c::c_int);
Expand Down
2 changes: 1 addition & 1 deletion src/clockid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ pub enum DynamicClockId<'a> {
Dynamic(BorrowedFd<'a>),

/// `CLOCK_REALTIME_ALARM`
#[cfg(linux_kernel)]
#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[doc(alias = "CLOCK_REALTIME_ALARM")]
RealtimeAlarm,

Expand Down
4 changes: 2 additions & 2 deletions src/time/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//! Time-related operations.

mod clock;
#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
mod timerfd;

// TODO: Convert WASI'S clock APIs to use handles rather than ambient clock
// identifiers, update `wasi-libc`, and then add support in `rustix`.
pub use clock::*;
#[cfg(any(linux_kernel, target_os = "fuchsia"))]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
pub use timerfd::*;
2 changes: 1 addition & 1 deletion tests/time/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ mod monotonic;
all(apple, not(target_os = "macos"))
)))]
mod settime;
#[cfg(linux_kernel)]
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
mod timerfd;
mod timespec;
#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
Expand Down

0 comments on commit c638fea

Please sign in to comment.