From 97333deb3f6713d7d12168c8980d69cc60961063 Mon Sep 17 00:00:00 2001
From: Yang Tse <yangsita@gmail.com>
Date: Wed, 2 Jul 2008 03:04:56 +0000
Subject: [PATCH] fallback to gettimeofday when monotonic clock is unavailable
 at run-time

---
 CHANGES              |  7 +++++++
 RELEASE-NOTES        |  2 +-
 acinclude.m4         | 30 ++++++------------------------
 ares/CHANGES         |  3 +++
 ares/RELEASE-NOTES   |  1 +
 ares/acinclude.m4    | 30 ++++++------------------------
 ares/ares__timeval.c | 21 ++++++++++++++++++---
 lib/timeval.c        | 21 ++++++++++++++++++---
 8 files changed, 60 insertions(+), 55 deletions(-)

diff --git a/CHANGES b/CHANGES
index bb5b5a1d2a..555c56253b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,13 @@
 
                                   Changelog
 
+Yang Tse (2 Jul 2008)
+- The previously committed fix for bug report #1999181 prevented using the
+  monotonic clock on any system without an always supported POSIX compliant
+  implementation. Now the POSIX compliant configuration check is removed and
+  will fallback to gettimeofday when the monotonic clock is unavailable at
+  run-time.
+
 Daniel Stenberg (1 Jul 2008)
 - Rolland Dudemaine provided fixes to get libcurl to build for the INTEGRITY
   operating system.
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index dc71abf06b..7c94905428 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -26,7 +26,7 @@ This release includes the following bugfixes:
  o SCP or SFTP over socks proxy crashed
  o RC4-MD5 cipher now works with NSS-built libcurl
  o range requests with --head are now done correctly
- o configure script misdetected monotonic clock availability
+ o fallback to gettimeofday when monotonic clock is unavailable at run-time
  o range numbers could be made to wrongly get output as signed
 
 This release includes the following known bugs:
diff --git a/acinclude.m4 b/acinclude.m4
index ce01ab45b2..f120559d51 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -1979,16 +1979,13 @@ dnl Check if monotonic clock_gettime is available.
 
 AC_DEFUN([CURL_CHECK_FUNC_CLOCK_GETTIME_MONOTONIC], [
   AC_REQUIRE([AC_HEADER_TIME])dnl
-  AC_CHECK_HEADERS(sys/types.h unistd.h sys/time.h time.h)
-  AC_MSG_CHECKING([for POSIX always supported monotonic clock_gettime])
+  AC_CHECK_HEADERS(sys/types.h sys/time.h time.h)
+  AC_MSG_CHECKING([for monotonic clock_gettime])
   AC_COMPILE_IFELSE([
     AC_LANG_PROGRAM([[
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #ifdef TIME_WITH_SYS_TIME
@@ -2000,16 +1997,8 @@ AC_DEFUN([CURL_CHECK_FUNC_CLOCK_GETTIME_MONOTONIC], [
 #endif
 #endif
     ]],[[
-#if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK > 0)
-      /*
-      The monotonic clock will not be used unless the feature test macro is
-      defined with a value greater than zero indicating _always_ supported.
-      */
       struct timespec ts;
       (void)clock_gettime(CLOCK_MONOTONIC, &ts);
-#else
-      HAVE_CLOCK_GETTIME_MONOTONIC shall not be defined.
-#endif
     ]])
   ],[
     AC_MSG_RESULT([yes])
@@ -2018,8 +2007,8 @@ AC_DEFUN([CURL_CHECK_FUNC_CLOCK_GETTIME_MONOTONIC], [
     AC_MSG_RESULT([no])
     ac_cv_func_clock_gettime="no"
   ])
-  dnl Definition of HAVE_CLOCK_GETTIME_MONOTONIC is intentionally
-  dnl postponed until library linking checks for clock_gettime pass.
+  dnl Definition of HAVE_CLOCK_GETTIME_MONOTONIC is intentionally postponed
+  dnl until library linking and run-time checks for clock_gettime succeed.
 ]) dnl AC_DEFUN
 
 
@@ -2050,9 +2039,6 @@ AC_DEFUN([CURL_CHECK_LIBS_CLOCK_GETTIME_MONOTONIC], [
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #ifdef TIME_WITH_SYS_TIME
@@ -2105,9 +2091,6 @@ AC_DEFUN([CURL_CHECK_LIBS_CLOCK_GETTIME_MONOTONIC], [
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #ifdef TIME_WITH_SYS_TIME
@@ -2119,12 +2102,11 @@ AC_DEFUN([CURL_CHECK_LIBS_CLOCK_GETTIME_MONOTONIC], [
 #endif
 #endif
         ]],[[
-#if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK > 0)
           struct timespec ts;
           if (0 == clock_gettime(CLOCK_MONOTONIC, &ts))
             exit(0);
-#endif
-          exit(1);
+          else
+            exit(1);
         ]])
       ],[
         AC_MSG_RESULT([yes])
diff --git a/ares/CHANGES b/ares/CHANGES
index 1266fb8548..ffe530d52c 100644
--- a/ares/CHANGES
+++ b/ares/CHANGES
@@ -1,5 +1,8 @@
   Changelog for the c-ares project
 
+* Jul 2 2008 (Yang Tse)
+- Fallback to gettimeofday when monotonic clock is unavailable at run-time.
+
 * Jun 30 2008 (Daniel Stenberg)
 
 - As was pointed out to me by Andreas Schuldei, the MAXHOSTNAMELEN define is
diff --git a/ares/RELEASE-NOTES b/ares/RELEASE-NOTES
index bad9445c83..6990b765f6 100644
--- a/ares/RELEASE-NOTES
+++ b/ares/RELEASE-NOTES
@@ -2,6 +2,7 @@ This is what's new and changed in the c-ares 1.5.3 release:
 
  o fix adig sample application compilation failure on some systems
  o fix pkg-config reporting of private libraries needed for static linking
+ o fallback to gettimeofday when monotonic clock is unavailable at run-time
 
 Thanks go to these friendly people for their efforts and contributions:
 
diff --git a/ares/acinclude.m4 b/ares/acinclude.m4
index 7a162bab36..79da24b18f 100644
--- a/ares/acinclude.m4
+++ b/ares/acinclude.m4
@@ -1446,16 +1446,13 @@ dnl Check if monotonic clock_gettime is available.
 
 AC_DEFUN([CURL_CHECK_FUNC_CLOCK_GETTIME_MONOTONIC], [
   AC_REQUIRE([AC_HEADER_TIME])dnl
-  AC_CHECK_HEADERS(sys/types.h unistd.h sys/time.h time.h)
-  AC_MSG_CHECKING([for POSIX always supported monotonic clock_gettime])
+  AC_CHECK_HEADERS(sys/types.h sys/time.h time.h)
+  AC_MSG_CHECKING([for monotonic clock_gettime])
   AC_COMPILE_IFELSE([
     AC_LANG_PROGRAM([[
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #ifdef TIME_WITH_SYS_TIME
@@ -1467,16 +1464,8 @@ AC_DEFUN([CURL_CHECK_FUNC_CLOCK_GETTIME_MONOTONIC], [
 #endif
 #endif
     ]],[[
-#if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK > 0)
-      /*
-      The monotonic clock will not be used unless the feature test macro is
-      defined with a value greater than zero indicating _always_ supported.
-      */
       struct timespec ts;
       (void)clock_gettime(CLOCK_MONOTONIC, &ts);
-#else
-      HAVE_CLOCK_GETTIME_MONOTONIC shall not be defined.
-#endif
     ]])
   ],[
     AC_MSG_RESULT([yes])
@@ -1485,8 +1474,8 @@ AC_DEFUN([CURL_CHECK_FUNC_CLOCK_GETTIME_MONOTONIC], [
     AC_MSG_RESULT([no])
     ac_cv_func_clock_gettime="no"
   ])
-  dnl Definition of HAVE_CLOCK_GETTIME_MONOTONIC is intentionally
-  dnl postponed until library linking checks for clock_gettime pass.
+  dnl Definition of HAVE_CLOCK_GETTIME_MONOTONIC is intentionally postponed
+  dnl until library linking and run-time checks for clock_gettime succeed.
 ]) dnl AC_DEFUN
 
 
@@ -1517,9 +1506,6 @@ AC_DEFUN([CURL_CHECK_LIBS_CLOCK_GETTIME_MONOTONIC], [
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #ifdef TIME_WITH_SYS_TIME
@@ -1572,9 +1558,6 @@ AC_DEFUN([CURL_CHECK_LIBS_CLOCK_GETTIME_MONOTONIC], [
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #ifdef TIME_WITH_SYS_TIME
@@ -1586,12 +1569,11 @@ AC_DEFUN([CURL_CHECK_LIBS_CLOCK_GETTIME_MONOTONIC], [
 #endif
 #endif
         ]],[[
-#if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK > 0)
           struct timespec ts;
           if (0 == clock_gettime(CLOCK_MONOTONIC, &ts))
             exit(0);
-#endif
-          exit(1);
+          else
+            exit(1);
         ]])
       ],[
         AC_MSG_RESULT([yes])
diff --git a/ares/ares__timeval.c b/ares/ares__timeval.c
index c3f39f523b..7437b5a18e 100644
--- a/ares/ares__timeval.c
+++ b/ares/ares__timeval.c
@@ -46,9 +46,24 @@ struct timeval ares__tvnow(void)
   */
   struct timeval now;
   struct timespec tsnow;
-  (void)clock_gettime(CLOCK_MONOTONIC, &tsnow);
-  now.tv_sec = tsnow.tv_sec;
-  now.tv_usec = tsnow.tv_nsec / 1000;
+  if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
+    now.tv_sec = tsnow.tv_sec;
+    now.tv_usec = tsnow.tv_nsec / 1000;
+  }
+  /*
+  ** Even when the configure process has truly detected monotonic clock
+  ** availability, it might happen that it is not actually available at
+  ** run-time. When this occurs simply fallback to other time source.
+  */
+#ifdef HAVE_GETTIMEOFDAY
+  else
+    (void)gettimeofday(&now, NULL);
+#else
+  else {
+    now.tv_sec = (long)time(NULL);
+    now.tv_usec = 0;
+  }
+#endif
   return now;
 }
 
diff --git a/lib/timeval.c b/lib/timeval.c
index 74f0b3a2ff..25ae763299 100644
--- a/lib/timeval.c
+++ b/lib/timeval.c
@@ -52,9 +52,24 @@ struct timeval curlx_tvnow(void)
   */
   struct timeval now;
   struct timespec tsnow;
-  (void)clock_gettime(CLOCK_MONOTONIC, &tsnow);
-  now.tv_sec = tsnow.tv_sec;
-  now.tv_usec = tsnow.tv_nsec / 1000;
+  if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
+    now.tv_sec = tsnow.tv_sec;
+    now.tv_usec = tsnow.tv_nsec / 1000;
+  }
+  /*
+  ** Even when the configure process has truly detected monotonic clock
+  ** availability, it might happen that it is not actually available at
+  ** run-time. When this occurs simply fallback to other time source.
+  */
+#ifdef HAVE_GETTIMEOFDAY
+  else
+    (void)gettimeofday(&now, NULL);
+#else
+  else {
+    now.tv_sec = (long)time(NULL);
+    now.tv_usec = 0;
+  }
+#endif
   return now;
 }
 
-- 
GitLab