From c0b58031ef8b98741f67d74662ba9128d43c5d03 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Wed, 21 Nov 2018 09:18:10 -0800
Subject: [PATCH] mktime: adjust to glibc 64-bit changes
* lib/mktime-internal.h (__gmtime64_r): Rename from __gmtime_r.
(__localtime64_r): Rename from __localtime_r.
(__mktime64, __time64_t, __timegm64): New macros.
* lib/mktime.c, lib/timegm.c: Sync from glibc, with changes
needed for Gnulib.
---
ChangeLog | 7 +++++
lib/mktime-internal.h | 14 ++++++---
lib/mktime.c | 68 ++++++++++++++++++++++++++-----------------
lib/timegm.c | 21 +++++++++++--
4 files changed, 77 insertions(+), 33 deletions(-)
@@ -1,5 +1,12 @@
2018-11-21 Paul Eggert <eggert@cs.ucla.edu>
+ mktime: adjust to glibc 64-bit changes
+ * lib/mktime-internal.h (__gmtime64_r): Rename from __gmtime_r.
+ (__localtime64_r): Rename from __localtime_r.
+ (__mktime64, __time64_t, __timegm64): New macros.
+ * lib/mktime.c, lib/timegm.c: Sync from glibc, with changes
+ needed for Gnulib.
+
mktime: add libc-config dependency
I missed this when we synced from glibc.
* modules/mktime (Depends-on): Add libc-config.
@@ -45,9 +45,15 @@ time_t mktime_internal (struct tm *,
Similarly for gmtime_r. See the gnulib time_r module for one way
to implement this. */
-#undef __gmtime_r
-#undef __localtime_r
-#define __gmtime_r gmtime_r
-#define __localtime_r localtime_r
+#undef __gmtime64_r
+#undef __localtime64_r
+#undef __mktime64
+#undef __time64_t
+#undef __timegm64
+#define __gmtime64_r gmtime_r
+#define __localtime64_r localtime_r
+#define __mktime64 mktime
+#define __time64_t time_t
+#define __timegm64 timegm
#define __mktime_internal mktime_internal
@@ -112,11 +112,11 @@ my_tzset (void)
added to them, and then with another timestamp added, without
worrying about overflow.
- Much of the code uses long_int to represent time_t values, to
- lessen the hassle of dealing with platforms where time_t is
+ Much of the code uses long_int to represent __time64_t values, to
+ lessen the hassle of dealing with platforms where __time64_t is
unsigned, and because long_int should suffice to represent all
- time_t values that mktime can generate even on platforms where
- time_t is excessively wide. */
+ __time64_t values that mktime can generate even on platforms where
+ __time64_t is excessively wide. */
#if INT_MAX <= LONG_MAX / 4 / 366 / 24 / 60 / 60
typedef long int long_int;
@@ -144,16 +144,17 @@ shr (long_int a, int b)
: a / (one << b) - (a % (one << b) < 0));
}
-/* Bounds for the intersection of time_t and long_int. */
+/* Bounds for the intersection of __time64_t and long_int. */
static long_int const mktime_min
- = ((TYPE_SIGNED (time_t) && TYPE_MINIMUM (time_t) < TYPE_MINIMUM (long_int))
- ? TYPE_MINIMUM (long_int) : TYPE_MINIMUM (time_t));
+ = ((TYPE_SIGNED (__time64_t)
+ && TYPE_MINIMUM (__time64_t) < TYPE_MINIMUM (long_int))
+ ? TYPE_MINIMUM (long_int) : TYPE_MINIMUM (__time64_t));
static long_int const mktime_max
- = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (time_t)
- ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (time_t));
+ = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (__time64_t)
+ ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (__time64_t));
-verify (TYPE_IS_INTEGER (time_t));
+verify (TYPE_IS_INTEGER (__time64_t));
#define EPOCH_YEAR 1970
#define TM_YEAR_BASE 1900
@@ -252,23 +253,23 @@ tm_diff (long_int year, long_int yday, int hour, int min, int sec,
}
/* Use CONVERT to convert T to a struct tm value in *TM. T must be in
- range for time_t. Return TM if successful, NULL (setting errno) on
+ range for __time64_t. Return TM if successful, NULL (setting errno) on
failure. */
static struct tm *
-convert_time (struct tm *(*convert) (const time_t *, struct tm *),
+convert_time (struct tm *(*convert) (const __time64_t *, struct tm *),
long_int t, struct tm *tm)
{
- time_t x = t;
+ __time64_t x = t;
return convert (&x, tm);
}
/* Use CONVERT to convert *T to a broken down time in *TP.
If *T is out of range for conversion, adjust it so that
it is the nearest in-range value and then convert that.
- A value is in range if it fits in both time_t and long_int.
+ A value is in range if it fits in both __time64_t and long_int.
Return TP on success, NULL (setting errno) on failure. */
static struct tm *
-ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
+ranged_convert (struct tm *(*convert) (const __time64_t *, struct tm *),
long_int *t, struct tm *tp)
{
long_int t1 = (*t < mktime_min ? mktime_min
@@ -310,7 +311,7 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
}
-/* Convert *TP to a time_t value, inverting
+/* Convert *TP to a __time64_t value, inverting
the monotonic and mostly-unit-linear conversion function CONVERT.
Use *OFFSET to keep track of a guess at the offset of the result,
compared to what the result would be for UTC without leap seconds.
@@ -318,9 +319,9 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
If successful, set *TP to the canonicalized struct tm;
otherwise leave *TP alone, return ((time_t) -1) and set errno.
This function is external because it is used also by timegm.c. */
-time_t
+__time64_t
__mktime_internal (struct tm *tp,
- struct tm *(*convert) (const time_t *, struct tm *),
+ struct tm *(*convert) (const __time64_t *, struct tm *),
mktime_offset_t *offset)
{
struct tm tm;
@@ -520,9 +521,9 @@ __mktime_internal (struct tm *tp,
#if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS
-/* Convert *TP to a time_t value. */
-time_t
-mktime (struct tm *tp)
+/* Convert *TP to a __time64_t value. */
+__time64_t
+__mktime64 (struct tm *tp)
{
/* POSIX.1 8.1.1 requires that whenever mktime() is called, the
time zone names contained in the external variable 'tzname' shall
@@ -531,19 +532,34 @@ mktime (struct tm *tp)
# if defined _LIBC || NEED_MKTIME_WORKING
static mktime_offset_t localtime_offset;
- return __mktime_internal (tp, __localtime_r, &localtime_offset);
+ return __mktime_internal (tp, __localtime64_r, &localtime_offset);
# else
# undef mktime
return mktime (tp);
# endif
}
+
+weak_alias (__mktime64, __timelocal64)
+libc_hidden_def (__mktime64)
+libc_hidden_weak (__timelocal64)
+
#endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */
-#ifdef weak_alias
-weak_alias (mktime, timelocal)
-#endif
+#if defined _LIBC && __TIMESIZE != 64
-#ifdef _LIBC
+/* The 32-bit-time wrapper. */
+time_t
+mktime (struct tm *tp)
+{
+ __time64_t t64 = __mktime64 (tp);
+ if (fits_in_time_t (t64))
+ return t64;
+ __set_errno (EOVERFLOW);
+ return -1;
+}
+
+weak_alias (mktime, timelocal)
libc_hidden_def (mktime)
libc_hidden_weak (timelocal)
+
#endif
@@ -24,11 +24,26 @@
#include <time.h>
#include "mktime-internal.h"
+#include <errno.h>
+
+__time64_t
+__timegm64 (struct tm *tmp)
+{
+ static long int gmtime_offset;
+ tmp->tm_isdst = 0;
+ return __mktime_internal (tmp, __gmtime64_r, &gmtime_offset);
+}
+
+#if defined _LIBC && __TIMESIZE != 64
time_t
timegm (struct tm *tmp)
{
- static mktime_offset_t gmtime_offset;
- tmp->tm_isdst = 0;
- return __mktime_internal (tmp, __gmtime_r, &gmtime_offset);
+ __time64_t t64 = __timegm64 (tmp);
+ if (fits_in_time_t (t64))
+ return t64;
+ __set_errno (EOVERFLOW);
+ return -1;
}
+
+#endif
--
2.17.1