147 lines
4.2 KiB
Diff
147 lines
4.2 KiB
Diff
diff -upNr b/lib/isc/include/isc/util.h a/lib/isc/include/isc/util.h
|
|
--- b/lib/isc/include/isc/util.h 2019-07-30 19:52:09.600000000 +0800
|
|
+++ a/lib/isc/include/isc/util.h 2019-07-30 21:39:03.400000000 +0800
|
|
@@ -233,7 +233,7 @@
|
|
* Time
|
|
*/
|
|
#define TIME_NOW(tp) RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS)
|
|
-
|
|
+#define TIME_REAL_NOW(tp) RUNTIME_CHECK(isc_time_real_now((tp)) == ISC_R_SUCCESS)
|
|
/*%
|
|
* Alignment
|
|
*/
|
|
diff -upNr b/lib/isc/log.c a/lib/isc/log.c
|
|
--- b/lib/isc/log.c 2019-07-30 19:52:09.610000000 +0800
|
|
+++ a/lib/isc/log.c 2019-07-30 21:39:03.410000000 +0800
|
|
@@ -1498,7 +1498,7 @@ isc_log_doit(isc_log_t *lctx, isc_logcat
|
|
time_string[0] == '\0') {
|
|
isc_time_t isctime;
|
|
|
|
- TIME_NOW(&isctime);
|
|
+ TIME_REAL_NOW(&isctime);
|
|
isc_time_formattimestamp(&isctime, time_string,
|
|
sizeof(time_string));
|
|
}
|
|
@@ -1545,7 +1545,7 @@ isc_log_doit(isc_log_t *lctx, isc_logcat
|
|
* which fall within the duplicate_interval
|
|
* range.
|
|
*/
|
|
- TIME_NOW(&oldest);
|
|
+ TIME_REAL_NOW(&oldest);
|
|
if (isc_time_subtract(&oldest, &interval,
|
|
&oldest)
|
|
!= ISC_R_SUCCESS)
|
|
@@ -1622,7 +1622,7 @@ isc_log_doit(isc_log_t *lctx, isc_logcat
|
|
strlcpy(message->text, lctx->buffer,
|
|
size);
|
|
|
|
- TIME_NOW(&message->time);
|
|
+ TIME_REAL_NOW(&message->time);
|
|
|
|
ISC_LINK_INIT(message, link);
|
|
ISC_LIST_APPEND(lctx->messages,
|
|
diff -upNr b/lib/isc/unix/include/isc/time.h a/lib/isc/unix/include/isc/time.h
|
|
--- b/lib/isc/unix/include/isc/time.h 2019-07-30 19:52:09.600000000 +0800
|
|
+++ a/lib/isc/unix/include/isc/time.h 2019-07-30 21:39:03.400000000 +0800
|
|
@@ -149,6 +149,8 @@ isc_time_now(isc_time_t *t);
|
|
*/
|
|
|
|
isc_result_t
|
|
+isc_time_real_now(isc_time_t *t);
|
|
+isc_result_t
|
|
isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i);
|
|
/*%<
|
|
* Set *t to the current absolute time + i.
|
|
diff -upNr b/lib/isc/unix/time.c a/lib/isc/unix/time.c
|
|
--- b/lib/isc/unix/time.c 2019-07-30 19:52:09.600000000 +0800
|
|
+++ a/lib/isc/unix/time.c 2019-07-30 21:39:03.400000000 +0800
|
|
@@ -36,6 +36,9 @@
|
|
#define NS_PER_MS 1000000 /*%< Nanoseconds per millisecond. */
|
|
#define US_PER_S 1000000 /*%< Microseconds per second. */
|
|
|
|
+#ifndef ISC_FIX_TV_USEC
|
|
+#define ISC_FIX_TV_USEC 1
|
|
+#endif
|
|
#define CLOCKSOURCE CLOCK_MONOTONIC
|
|
|
|
/*%
|
|
@@ -44,6 +47,27 @@
|
|
|
|
static const isc_interval_t zero_interval = { 0, 0 };
|
|
const isc_interval_t * const isc_interval_zero = &zero_interval;
|
|
+#if ISC_FIX_TV_USEC
|
|
+static inline void
|
|
+fix_tv_usec(struct timeval *tv) {
|
|
+ isc_boolean_t fixed = ISC_FALSE;
|
|
+ if (tv->tv_usec < 0) {
|
|
+ fixed = ISC_TRUE;
|
|
+ do {
|
|
+ tv->tv_sec -= 1;
|
|
+ tv->tv_usec += US_PER_S;
|
|
+ } while (tv->tv_usec < 0);
|
|
+ } else if (tv->tv_usec >= US_PER_S) {
|
|
+ fixed = ISC_TRUE;
|
|
+ do {
|
|
+ tv->tv_sec += 1;
|
|
+ tv->tv_usec -= US_PER_S;
|
|
+ } while (tv->tv_usec >=US_PER_S);
|
|
+ }
|
|
+ if (fixed)
|
|
+ (void)syslog(LOG_ERR, "gettimeofday returned bad tv_usec: corrected");
|
|
+}
|
|
+#endif
|
|
|
|
void
|
|
isc_interval_set(isc_interval_t *i,
|
|
@@ -105,6 +129,50 @@ isc_time_isepoch(const isc_time_t *t) {
|
|
|
|
|
|
isc_result_t
|
|
+isc_time_real_now(isc_time_t *t) {
|
|
+ struct timeval tv;
|
|
+ char strbuf[ISC_STRERRORSIZE];
|
|
+
|
|
+ REQUIRE(t != NULL);
|
|
+
|
|
+ if (gettimeofday(&tv, NULL) == -1) {
|
|
+ isc__strerror(errno, strbuf, sizeof(strbuf));
|
|
+ UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf);
|
|
+ return (ISC_R_UNEXPECTED);
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Does POSIX guarantee the signedness of tv_sec and tv_usec? If not,
|
|
+ * then this test will generate warnings for platforms on which it is
|
|
+ * unsigned. In any event, the chances of any of these problems
|
|
+ * happening are pretty much zero, but since the libisc library ensures
|
|
+ * certain things to be true ...
|
|
+ */
|
|
+#if ISC_FIX_TV_USEC
|
|
+ fix_tv_usec(&tv);
|
|
+ if (tv.tv_sec < 0)
|
|
+ return (ISC_R_UNEXPECTED);
|
|
+#else
|
|
+ if (tv.tv_sec < 0 || tv.tv_usec < 0 || tv.tv_usec >= US_PER_S)
|
|
+ return (ISC_R_UNEXPECTED);
|
|
+#endif
|
|
+
|
|
+ /*
|
|
+ * Ensure the tv_sec value fits in t->seconds.
|
|
+ */
|
|
+ if (sizeof(tv.tv_sec) > sizeof(t->seconds) &&
|
|
+ ((tv.tv_sec | (unsigned int)-1) ^ (unsigned int)-1) != 0U)
|
|
+ return (ISC_R_RANGE);
|
|
+
|
|
+ t->seconds = tv.tv_sec;
|
|
+ t->nanoseconds = tv.tv_usec * NS_PER_US;
|
|
+
|
|
+ return (ISC_R_SUCCESS);
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+isc_result_t
|
|
isc_time_now(isc_time_t *t) {
|
|
struct timespec ts;
|
|
char strbuf[ISC_STRERRORSIZE];
|