|
@@ -1996,14 +1996,88 @@ tor_gettimeofday(struct timeval *timeval)
|
|
|
#define TIME_FNS_NEED_LOCKS
|
|
|
#endif
|
|
|
|
|
|
+static struct tm *
|
|
|
+correct_tm(int islocal, const time_t *timep, struct tm *resultbuf,
|
|
|
+ struct tm *r)
|
|
|
+{
|
|
|
+ const char *outcome;
|
|
|
+
|
|
|
+ if (PREDICT_LIKELY(r)) {
|
|
|
+ if (r->tm_year > 8099) {
|
|
|
+ r->tm_year = 8099;
|
|
|
+ r->tm_mon = 11;
|
|
|
+ r->tm_mday = 31;
|
|
|
+ r->tm_yday = 365;
|
|
|
+ r->tm_hour = 23;
|
|
|
+ r->tm_min = 59;
|
|
|
+ r->tm_sec = 59;
|
|
|
+ }
|
|
|
+ return r;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * this because of overrun or underrun, or it might have done it because of
|
|
|
+ * some other weird issue. */
|
|
|
+ if (timep) {
|
|
|
+ if (*timep < 0) {
|
|
|
+ r = resultbuf;
|
|
|
+ r->tm_year = 70;
|
|
|
+ r->tm_mon = 0;
|
|
|
+ r->tm_mday = 1;
|
|
|
+ r->tm_yday = 1;
|
|
|
+ r->tm_hour = 0;
|
|
|
+ r->tm_min = 0 ;
|
|
|
+ r->tm_sec = 0;
|
|
|
+ outcome = "Rounding up to 1970";
|
|
|
+ goto done;
|
|
|
+ } else if (*timep >= INT32_MAX) {
|
|
|
+
|
|
|
+ * only do it if gmtime/localtime tells us NULL. */
|
|
|
+ r = resultbuf;
|
|
|
+ r->tm_year = 137;
|
|
|
+ r->tm_mon = 11;
|
|
|
+ r->tm_mday = 31;
|
|
|
+ r->tm_yday = 365;
|
|
|
+ r->tm_hour = 23;
|
|
|
+ r->tm_min = 59;
|
|
|
+ r->tm_sec = 59;
|
|
|
+ outcome = "Rounding down to 2037";
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * value for *timep */
|
|
|
+
|
|
|
+ tor_fragile_assert();
|
|
|
+ r = resultbuf;
|
|
|
+ memset(resultbuf, 0, sizeof(struct tm));
|
|
|
+ outcome="can't recover";
|
|
|
+ done:
|
|
|
+ log_warn(LD_BUG, "%s("I64_FORMAT") failed with error %s: %s",
|
|
|
+ islocal?"localtime":"gmtime",
|
|
|
+ timep?I64_PRINTF_ARG(*timep):0,
|
|
|
+ strerror(errno),
|
|
|
+ outcome);
|
|
|
+ return r;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
*
|
|
|
* Convert *<b>timep</b> to a struct tm in local time, and store the value in
|
|
|
* *<b>result</b>. Return the result on success, or NULL on failure.
|
|
|
*/
|
|
|
-#ifndef HAVE_LOCALTIME_R
|
|
|
-#ifdef TIME_FNS_NEED_LOCKS
|
|
|
+#ifdef HAVE_LOCALTIME_R
|
|
|
+struct tm *
|
|
|
+tor_localtime_r(const time_t *timep, struct tm *result)
|
|
|
+{
|
|
|
+ struct tm *r;
|
|
|
+ r = localtime_r(timep, result);
|
|
|
+ return correct_tm(1, timep, result, r);
|
|
|
+}
|
|
|
+#elif defined(TIME_FNS_NEED_LOCKS)
|
|
|
struct tm *
|
|
|
tor_localtime_r(const time_t *timep, struct tm *result)
|
|
|
{
|
|
@@ -2013,9 +2087,10 @@ tor_localtime_r(const time_t *timep, struct tm *result)
|
|
|
tor_assert(result);
|
|
|
tor_mutex_acquire(m);
|
|
|
r = localtime(timep);
|
|
|
- memcpy(result, r, sizeof(struct tm));
|
|
|
+ if (r)
|
|
|
+ memcpy(result, r, sizeof(struct tm));
|
|
|
tor_mutex_release(m);
|
|
|
- return result;
|
|
|
+ return correct_tm(1, timep, result, r);
|
|
|
}
|
|
|
#else
|
|
|
struct tm *
|
|
@@ -2024,11 +2099,11 @@ tor_localtime_r(const time_t *timep, struct tm *result)
|
|
|
struct tm *r;
|
|
|
tor_assert(result);
|
|
|
r = localtime(timep);
|
|
|
- memcpy(result, r, sizeof(struct tm));
|
|
|
- return result;
|
|
|
+ if (r)
|
|
|
+ memcpy(result, r, sizeof(struct tm));
|
|
|
+ return correct_tm(1, timep, result, r);
|
|
|
}
|
|
|
#endif
|
|
|
-#endif
|
|
|
|
|
|
|
|
|
|
|
@@ -2038,7 +2113,14 @@ tor_localtime_r(const time_t *timep, struct tm *result)
|
|
|
* *<b>result</b>. Return the result on success, or NULL on failure.
|
|
|
*/
|
|
|
#ifndef HAVE_GMTIME_R
|
|
|
-#ifdef TIME_FNS_NEED_LOCKS
|
|
|
+struct tm *
|
|
|
+tor_gmtime_r(const time_t *timep, struct tm *result)
|
|
|
+{
|
|
|
+ struct tm *r;
|
|
|
+ r = gmtime_r(timep, result);
|
|
|
+ return correct_tm(0, timep, result, r);
|
|
|
+}
|
|
|
+#elif defined(TIME_FNS_NEED_LOCKS)
|
|
|
struct tm *
|
|
|
tor_gmtime_r(const time_t *timep, struct tm *result)
|
|
|
{
|
|
@@ -2050,7 +2132,7 @@ tor_gmtime_r(const time_t *timep, struct tm *result)
|
|
|
r = gmtime(timep);
|
|
|
memcpy(result, r, sizeof(struct tm));
|
|
|
tor_mutex_release(m);
|
|
|
- return result;
|
|
|
+ return correct_tm(0, timep, result, r);
|
|
|
}
|
|
|
#else
|
|
|
struct tm *
|
|
@@ -2060,11 +2142,9 @@ tor_gmtime_r(const time_t *timep, struct tm *result)
|
|
|
tor_assert(result);
|
|
|
r = gmtime(timep);
|
|
|
memcpy(result, r, sizeof(struct tm));
|
|
|
- return result;
|
|
|
+ return correct_tm(0, timep, result, r);
|
|
|
}
|
|
|
#endif
|
|
|
-#endif
|
|
|
-
|
|
|
|
|
|
#if defined(USE_WIN32_THREADS)
|
|
|
void
|