Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support the timerfd API on FreeBSD. #978

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading