From a5d3154c04ca3167cfb99c256401cbe55ebb7fc7 Mon Sep 17 00:00:00 2001 From: David Venhoek Date: Thu, 10 Aug 2023 14:40:38 +0200 Subject: [PATCH] Switch to own TimeOffset time to deal with signed offset. --- src/lib.rs | 11 +++++++++-- src/unix.rs | 40 +++++++++++++++++++--------------------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6c91215..6d1725c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,8 +13,15 @@ pub mod unix; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] pub struct Timestamp { pub seconds: libc::time_t, + /// Nanos must be between 0 and 999999999 inclusive + pub nanos: u32, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +pub struct TimeOffset { + pub seconds: libc::time_t, + /// Nanos must be between 0 and 999999999 inclusive pub nanos: u32, - pub subnanos: u32, } /// Indicate whether a leap second must be applied @@ -56,7 +63,7 @@ pub trait Clock { /// Change the current time of the clock by an offset. /// Returns the time at which the change was applied. - fn step_clock(&self, offset: Duration) -> Result; + fn step_clock(&self, offset: TimeOffset) -> Result; /// Change the indicators for upcoming leap seconds. fn set_leap_seconds(&self, leap_status: LeapIndicator) -> Result<(), Self::Error>; diff --git a/src/unix.rs b/src/unix.rs index 2895ee0..c36520a 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -1,4 +1,4 @@ -use crate::{Clock, LeapIndicator, Timestamp}; +use crate::{Clock, LeapIndicator, TimeOffset, Timestamp}; use std::{ os::unix::prelude::{AsRawFd, FromRawFd, RawFd}, path::Path, @@ -157,17 +157,14 @@ impl UnixClock { } #[cfg_attr(target_os = "linux", allow(unused))] - fn step_clock_by_timespec(&self, offset: Duration) -> Result { - let offset_secs = offset.as_secs(); - let offset_nanos = offset.subsec_nanos(); - + fn step_clock_by_timespec(&self, offset: TimeOffset) -> Result { let mut timespec = self.clock_gettime()?; // see https://github.com/rust-lang/libc/issues/1848 #[cfg_attr(target_env = "musl", allow(deprecated))] { - timespec.tv_sec += offset_secs as libc::time_t; - timespec.tv_nsec += offset_nanos as libc::c_long; + timespec.tv_sec += offset.seconds as libc::time_t; + timespec.tv_nsec += offset.nanos as libc::c_long; } self.clock_settime(timespec)?; @@ -191,13 +188,13 @@ impl UnixClock { } #[cfg(target_os = "linux")] - fn step_clock_timex(offset: Duration) -> libc::timex { + fn step_clock_timex(offset: TimeOffset) -> libc::timex { // we provide the offset in nanoseconds let modes = libc::ADJ_SETOFFSET | libc::ADJ_NANO; let time = libc::timeval { - tv_sec: offset.as_secs() as _, - tv_usec: offset.subsec_nanos() as libc::suseconds_t, + tv_sec: offset.seconds, + tv_usec: offset.nanos as libc::suseconds_t, }; libc::timex { @@ -208,7 +205,7 @@ impl UnixClock { } #[cfg(target_os = "linux")] - fn step_clock_by_timex(&self, offset: Duration) -> Result { + fn step_clock_by_timex(&self, offset: TimeOffset) -> Result { let mut timex = Self::step_clock_timex(offset); self.adjtime(&mut timex)?; self.extract_current_time(&timex) @@ -378,12 +375,12 @@ impl Clock for UnixClock { } #[cfg(target_os = "linux")] - fn step_clock(&self, offset: Duration) -> Result { + fn step_clock(&self, offset: TimeOffset) -> Result { self.step_clock_by_timex(offset) } #[cfg(any(target_os = "freebsd", target_os = "macos"))] - fn step_clock(&self, offset: Duration) -> Result { + fn step_clock(&self, offset: TimeOffset) -> Result { self.step_clock_by_timespec(offset) } @@ -537,7 +534,6 @@ fn current_time_timespec(timespec: libc::timespec, precision: Precision) -> Time Timestamp { seconds, nanos: nanos as u32, - subnanos: 0, } } @@ -551,11 +547,7 @@ fn current_time_timeval(timespec: libc::timeval, precision: Precision) -> Timest .unwrap_or_default(), }; - Timestamp { - seconds, - nanos, - subnanos: 0, - } + Timestamp { seconds, nanos } } const EMPTY_TIMESPEC: libc::timespec = libc::timespec { @@ -694,7 +686,10 @@ mod tests { #[ignore = "requires permissions, useful for testing permissions"] fn step_clock() { UnixClock::CLOCK_REALTIME - .step_clock(Duration::new(0, 0)) + .step_clock(TimeOffset { + seconds: 0, + nanos: 0, + }) .unwrap(); } @@ -743,7 +738,10 @@ mod tests { #[cfg(target_os = "linux")] #[test] fn test_step_clock() { - let offset = Duration::from_secs_f64(1.2); + let offset = TimeOffset { + seconds: 1, + nanos: 200000000, + }; let timex = UnixClock::step_clock_timex(offset); assert_eq!(timex.modes, libc::ADJ_SETOFFSET | libc::ADJ_NANO);