From 91de1c836708ce6c35ef25ea56ca86cf612fbaf6 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sun, 25 Dec 2022 11:28:28 +0000 Subject: fix $request_time{9,0} for 32-bit platforms `struct timespec' has 32-bit tv_sec and tv_nsec on 32-bit x86 GNU/Linux system, causing excessive overflow and test failures. --- ext/clogger_ext/clogger.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/ext/clogger_ext/clogger.c b/ext/clogger_ext/clogger.c index 2ec9510..8cd40be 100644 --- a/ext/clogger_ext/clogger.c +++ b/ext/clogger_ext/clogger.c @@ -386,30 +386,29 @@ static void append_request_time_fmt(struct clogger *c, VALUE op) clock_gettime(hopefully_CLOCK_MONOTONIC, &now); clock_diff(&now, &c->ts_start); if (ipow) { - struct timespec prev; unsigned long adj = 1; - /* - * n.b. timespec.tv_sec may not be time_t on some platforms, - * so we use a full timespec struct instead of time_t: - */ - prev.tv_sec = now.tv_sec; + int64_t now_sec = now.tv_sec, now_nsec = now.tv_nsec, + prev_sec = now.tv_sec; + do { adj *= 10; } while (--ipow); - now.tv_sec *= adj; - now.tv_nsec *= adj; - if (now.tv_nsec >= NANO_PER_SEC) { - int64_t add = now.tv_nsec / NANO_PER_SEC; - now.tv_sec += add; - now.tv_nsec %= NANO_PER_SEC; + now_sec *= adj; + now_nsec *= adj; + if (now_nsec >= NANO_PER_SEC) { + int64_t add = now_nsec / NANO_PER_SEC; + now_sec += add; + now_nsec %= NANO_PER_SEC; } - if (now.tv_sec < prev.tv_sec) { /* overflowed */ - now.tv_nsec = NANO_PER_SEC - 1; + if (now_sec < prev_sec) { /* overflowed */ + now_nsec = NANO_PER_SEC - 1; /* * some platforms may use unsigned .tv_sec, but * they're not worth supporting, so keep unsigned: */ - now.tv_sec = (time_t)(sizeof(now.tv_sec) == 4 ? + now_sec = (time_t)(sizeof(now.tv_sec) == 4 ? INT_MAX : LONG_MAX); } + now.tv_sec = now_sec; + now.tv_nsec = now_nsec; } append_ts(c, op, &now); } -- cgit v1.2.3-24-ge0c7