From 7aeecf3e0b5462a05f7173993618eb59ba1a86d5 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sun, 28 Jul 2019 18:43:51 -0400 Subject: [PATCH] clock_settime: add time64 syscall support, decouple 32-bit time_t time64 syscall is used only if it's the only one defined for the arch, or if the requested time does not fit in 32 bits. on current 32-bit archs where time_t is a 32-bit type, this makes it statically unreachable. if the time64 syscall is needed because the requested time does not fit in 32 bits, we define this as an error ENOTSUP, for "The implementation does not support the requested feature or value". on 64-bit archs, there is no change to the code after preprocessing. on current 32-bit archs, the time is moved through an intermediate copy to remove the assumption that time_t is a 32-bit type. --- src/time/clock_settime.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/time/clock_settime.c b/src/time/clock_settime.c index 66b8162d..5fdaeb9e 100644 --- a/src/time/clock_settime.c +++ b/src/time/clock_settime.c @@ -1,7 +1,24 @@ #include +#include #include "syscall.h" +#define IS32BIT(x) !((x)+0x80000000ULL>>32) + int clock_settime(clockid_t clk, const struct timespec *ts) { +#ifdef SYS_clock_settime64 + time_t s = ts->tv_sec; + long ns = ts->tv_nsec; + int r = -ENOSYS; + if (SYS_clock_settime == SYS_clock_settime64 || !IS32BIT(s)) + r = __syscall(SYS_clock_settime64, clk, + ((long long[]){s, ns})); + if (SYS_clock_settime == SYS_clock_settime64 || r!=-ENOSYS) + return __syscall_ret(r); + if (!IS32BIT(s)) + return __syscall_ret(-ENOTSUP); + return syscall(SYS_clock_settime, clk, ts ? ((long[]){s, ns}) : 0); +#else return syscall(SYS_clock_settime, clk, ts); +#endif }