about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <bofh@yhbt.net>2022-12-25 11:28:28 +0000
committerEric Wong <bofh@yhbt.net>2022-12-25 11:47:07 +0000
commit91de1c836708ce6c35ef25ea56ca86cf612fbaf6 (patch)
tree3e07b9f19b366e8e715d0b3b61cd961799577315
parente0efbc362b578d78f3c7f1fa584b2f9fd518c8d0 (diff)
downloadclogger-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.c29
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);
 }