|
@@ -146,6 +146,14 @@
|
|
|
#include <bits/uClibc_uintmaxtostr.h>
|
|
#include <bits/uClibc_uintmaxtostr.h>
|
|
|
#include <bits/uClibc_mutex.h>
|
|
#include <bits/uClibc_mutex.h>
|
|
|
|
|
|
|
|
|
|
+/* Largest value a time_t can hold, named without assuming its width -- the
|
|
|
|
|
+ * places below that need it used to reach for LONG_MAX, which is not the same
|
|
|
|
|
+ * thing once UCLIBC_USE_TIME64 gives a 32-bit target a 64-bit time_t. If
|
|
|
|
|
+ * time_t is unsigned this yields half its range, which only makes the tests
|
|
|
|
|
+ * that use it trigger earlier, never later. */
|
|
|
|
|
+#define TIME_T_MAX \
|
|
|
|
|
+ ((time_t)(~(uintmax_t)0 >> (8 * (sizeof(uintmax_t) - sizeof(time_t)) + 1)))
|
|
|
|
|
+
|
|
|
#if defined __UCLIBC_HAS_WCHAR__ && (defined L_wcsftime || defined L_wcsftime_l)
|
|
#if defined __UCLIBC_HAS_WCHAR__ && (defined L_wcsftime || defined L_wcsftime_l)
|
|
|
#include <wchar.h>
|
|
#include <wchar.h>
|
|
|
# define CHAR_T wchar_t
|
|
# define CHAR_T wchar_t
|
|
@@ -748,11 +756,22 @@ struct tm attribute_hidden *__time_localtime_tzi(register const time_t *__restri
|
|
|
|
|
|
|
|
dst = 0;
|
|
dst = 0;
|
|
|
do {
|
|
do {
|
|
|
|
|
+ /* _time_t2tm() is handed the time a week ahead and a -7 day
|
|
|
|
|
+ * correction, so that a 32-bit time_t stays non-negative while
|
|
|
|
|
+ * the zone offset is applied. Near the top of the range that
|
|
|
|
|
+ * week would overflow, so it is subtracted instead -- but only
|
|
|
|
|
+ * the week changes sign, never the zone offset. Negating the
|
|
|
|
|
+ * whole sum moved the clock by twice the offset.
|
|
|
|
|
+ *
|
|
|
|
|
+ * The bound follows time_t. It used to be LONG_MAX, which is
|
|
|
|
|
+ * 2^31-1 on the 32-bit targets that set UCLIBC_USE_TIME64:
|
|
|
|
|
+ * every date past January 2038 took the fallback path there,
|
|
|
|
|
+ * so localtime() was off by 2*gmtoff in every zone but UTC. */
|
|
|
days = -7;
|
|
days = -7;
|
|
|
offset = 604800L - tzi[dst].gmt_offset;
|
|
offset = 604800L - tzi[dst].gmt_offset;
|
|
|
- if (*timer > (LONG_MAX - 604800L)) {
|
|
|
|
|
|
|
+ if (*timer > (TIME_T_MAX - 604800L)) {
|
|
|
days = -days;
|
|
days = -days;
|
|
|
- offset = -offset;
|
|
|
|
|
|
|
+ offset = -604800L - tzi[dst].gmt_offset;
|
|
|
}
|
|
}
|
|
|
*x = *timer + offset;
|
|
*x = *timer + offset;
|
|
|
|
|
|