diff --git a/src/header/time/constants.rs b/src/header/time/constants.rs index 2a89e49e54..34f0056573 100644 --- a/src/header/time/constants.rs +++ b/src/header/time/constants.rs @@ -22,3 +22,12 @@ pub const CLOCK_PROCESS_CPUTIME_ID: clockid_t = 2; pub const CLOCKS_PER_SEC: c_long = 1_000_000; pub const TIMER_ABSTIME: c_int = 1; + +// Constants for timespec_get and timespec_getres which are C23 analogues to +// clock_gettime/getres. +// The values are offset by one for simplicity since zero represents an error. + +/// `TIME_UTC` returns the time since the Unix epoch. +pub const TIME_UTC: c_int = sys::CLOCK_REALTIME + 1; +/// `TIME_MONOTONIC` returns the time from the monotonically increasing clock. +pub const TIME_MONOTONIC: c_int = sys::CLOCK_MONOTONIC + 1; diff --git a/src/header/time/mod.rs b/src/header/time/mod.rs index 1420509669..51d56b66ed 100644 --- a/src/header/time/mod.rs +++ b/src/header/time/mod.rs @@ -599,10 +599,27 @@ pub unsafe extern "C" fn timer_settime( .or_minus_one_errno() } +/// ISO C equivalent to [`Sys::clock_gettime`]. +/// +/// The main differences are that this function: +/// * returns `0` on error and `base` on success +/// * only mandates TIME_UTC as a base +/// /// See . -// #[unsafe(no_mangle)] -pub extern "C" fn timespec_get(ts: *mut timespec, base: c_int) -> c_int { - unimplemented!(); +#[unsafe(no_mangle)] +pub extern "C" fn timespec_get(tp: *mut timespec, base: c_int) -> c_int { + let tp = unsafe { Out::nonnull(tp) }; + Sys::clock_gettime(base - 1, tp).map(|()| base).unwrap_or(0) +} + +/// ISO C equivalent to [`Sys::clock_getres`]. +/// +/// The main differences are that this function: +/// * returns `0` on error and `base` on success +/// * only mandates TIME_UTC as a base +pub extern "C" fn timespec_getres(res: *mut timespec, base: c_int) -> c_int { + let res = unsafe { Out::nullable(res) }; + Sys::clock_getres(base - 1, res).map(|()| base).unwrap_or(0) } /// See . diff --git a/tests/time/time.c b/tests/time/time.c index 263e9596d5..0655cc50a3 100644 --- a/tests/time/time.c +++ b/tests/time/time.c @@ -1,19 +1,44 @@ -#include -#include +#include #include +#include #include "test_helpers.h" int main(void) { - struct timespec tm = {0, 0}; + struct timespec tm = {0}; int cgt = clock_gettime(CLOCK_REALTIME, &tm); ERROR_IF(clock_gettime, cgt, == -1); + cgt = clock_getres(CLOCK_REALTIME, &tm); + ERROR_IF(clock_getres, cgt, == -1); + + cgt = timespec_get(&tm, TIME_UTC); + if (cgt != TIME_UTC) { + errx( + EXIT_FAILURE, + "timespec_get should have returned %d but returned %d\n", + TIME_UTC, + cgt + ); + } + + cgt = timespec_getres(&tm, TIME_UTC); + if (cgt != TIME_UTC) { + errx( + EXIT_FAILURE, + "timespec_getres should have returned %d but returned %d\n", + TIME_UTC, + cgt + ); + } + time_t t = time(NULL); ERROR_IF(time, t, == (time_t)-1); // TODO: Support clock() on Redox // clock_t c = clock(); // ERROR_IF(clock, c, == (clock_t)-1); + + return EXIT_SUCCESS; }