diff options
author | Eric Wong <bofh@yhbt.net> | 2022-12-25 11:28:28 +0000 |
---|---|---|
committer | Eric Wong <bofh@yhbt.net> | 2022-12-25 11:47:07 +0000 |
commit | 91de1c836708ce6c35ef25ea56ca86cf612fbaf6 (patch) | |
tree | 3e07b9f19b366e8e715d0b3b61cd961799577315 | |
parent | e0efbc362b578d78f3c7f1fa584b2f9fd518c8d0 (diff) | |
download | clogger-91de1c836708ce6c35ef25ea56ca86cf612fbaf6.tar.gz |
`struct timespec' has 32-bit tv_sec and tv_nsec on 32-bit x86 GNU/Linux system, causing excessive overflow and test failures.
-rw-r--r-- | ext/clogger_ext/clogger.c | 29 |
1 files 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); } |