aboutsummaryrefslogtreecommitdiff
path: root/time/mktime.c
diff options
context:
space:
mode:
Diffstat (limited to 'time/mktime.c')
-rw-r--r--time/mktime.c71
1 files changed, 44 insertions, 27 deletions
diff --git a/time/mktime.c b/time/mktime.c
index 57efee9..8fe2f96 100644
--- a/time/mktime.c
+++ b/time/mktime.c
@@ -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 wider than the int components of struct tm. */
#if INT_MAX <= LONG_MAX / 4 / 366 / 24 / 60 / 60
typedef long int long_int;
@@ -144,16 +144,15 @@ 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));
-
-verify (TYPE_IS_INTEGER (time_t));
+ = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (__time64_t)
+ ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (__time64_t));
#define EPOCH_YEAR 1970
#define TM_YEAR_BASE 1900
@@ -252,23 +251,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 +309,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 +317,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 +519,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,7 +530,7 @@ 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);
@@ -539,11 +538,29 @@ mktime (struct tm *tp)
}
#endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */
-#ifdef weak_alias
-weak_alias (mktime, timelocal)
+#if defined _LIBC && __TIMESIZE != 64
+
+libc_hidden_def (__mktime64)
+
+time_t
+mktime (struct tm *tp)
+{
+ struct tm tm = *tp;
+ __time64_t t = __mktime64 (&tm);
+ if (in_time_t_range (t))
+ {
+ *tp = tm;
+ return t;
+ }
+ else
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+}
+
#endif
-#ifdef _LIBC
+weak_alias (mktime, timelocal)
libc_hidden_def (mktime)
libc_hidden_weak (timelocal)
-#endif