diff options
author | Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> | 2018-12-05 21:01:22 +0100 |
---|---|---|
committer | Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> | 2018-12-05 21:01:22 +0100 |
commit | 72b8692d7e640eb85ea0fb7de6d5e797512691c1 (patch) | |
tree | 5e98d09fcf975415b8cac7237764d565f6ebddaa /time | |
parent | bd598da9f454bc1091b4ebe0303b07e6f96ca130 (diff) | |
download | glibc-72b8692d7e640eb85ea0fb7de6d5e797512691c1.zip glibc-72b8692d7e640eb85ea0fb7de6d5e797512691c1.tar.gz glibc-72b8692d7e640eb85ea0fb7de6d5e797512691c1.tar.bz2 |
Y2038: make __tz_convert compatible with 64-bit-time
Now that __time64_t exists, we can switch internal function
__tz_convert from 32-bit to 64-bit time. This involves switching
some other internal functions as well, namely __tz_compute and
__offtime.
Tested with 'make check' on x86_64-linux-gnu and i686-linux.gnu.
* include/time.h
(__tz_compute): Replace time_t with __time64_t.
(__tz_convert): Replace time_t* with __time64_t.
(__offtime): Replace time_t* with __time64_t.
* time/gmtime.c
(__gmtime_r): Adjust call to __tz_convert.
(gmtime): Likewise.
* time/localtime.c
(__localtime_r): Likewise.
(localtime): Likewise.
* time/offtime.c: Replace time_t with __time64_t.
* time/tzset.c: Likewise.
Diffstat (limited to 'time')
-rw-r--r-- | time/gmtime.c | 4 | ||||
-rw-r--r-- | time/localtime.c | 4 | ||||
-rw-r--r-- | time/offtime.c | 12 | ||||
-rw-r--r-- | time/tzfile.c | 14 | ||||
-rw-r--r-- | time/tzset.c | 27 |
5 files changed, 24 insertions, 37 deletions
diff --git a/time/gmtime.c b/time/gmtime.c index dc33b3e..bda09bc 100644 --- a/time/gmtime.c +++ b/time/gmtime.c @@ -23,7 +23,7 @@ struct tm * __gmtime_r (const time_t *t, struct tm *tp) { - return __tz_convert (t, 0, tp); + return __tz_convert (*t, 0, tp); } libc_hidden_def (__gmtime_r) weak_alias (__gmtime_r, gmtime_r) @@ -33,5 +33,5 @@ weak_alias (__gmtime_r, gmtime_r) struct tm * gmtime (const time_t *t) { - return __tz_convert (t, 0, &_tmbuf); + return __tz_convert (*t, 0, &_tmbuf); } diff --git a/time/localtime.c b/time/localtime.c index 8684a8a..92dbfe0 100644 --- a/time/localtime.c +++ b/time/localtime.c @@ -27,7 +27,7 @@ struct tm _tmbuf; struct tm * __localtime_r (const time_t *t, struct tm *tp) { - return __tz_convert (t, 1, tp); + return __tz_convert (*t, 1, tp); } weak_alias (__localtime_r, localtime_r) @@ -36,6 +36,6 @@ weak_alias (__localtime_r, localtime_r) struct tm * localtime (const time_t *t) { - return __tz_convert (t, 1, &_tmbuf); + return __tz_convert (*t, 1, &_tmbuf); } libc_hidden_def (localtime) diff --git a/time/offtime.c b/time/offtime.c index 04c4838..3309fcd 100644 --- a/time/offtime.c +++ b/time/offtime.c @@ -21,18 +21,18 @@ #define SECS_PER_HOUR (60 * 60) #define SECS_PER_DAY (SECS_PER_HOUR * 24) -/* Compute the `struct tm' representation of *T, +/* Compute the `struct tm' representation of T, offset OFFSET seconds east of UTC, and store year, yday, mon, mday, wday, hour, min, sec into *TP. Return nonzero if successful. */ int -__offtime (const time_t *t, long int offset, struct tm *tp) +__offtime (__time64_t t, long int offset, struct tm *tp) { - time_t days, rem, y; + __time64_t days, rem, y; const unsigned short int *ip; - days = *t / SECS_PER_DAY; - rem = *t % SECS_PER_DAY; + days = t / SECS_PER_DAY; + rem = t % SECS_PER_DAY; rem += offset; while (rem < 0) { @@ -60,7 +60,7 @@ __offtime (const time_t *t, long int offset, struct tm *tp) while (days < 0 || days >= (__isleap (y) ? 366 : 365)) { /* Guess a corrected year, assuming 365 days per year. */ - time_t yg = y + days / 365 - (days % 365 < 0); + __time64_t yg = y + days / 365 - (days % 365 < 0); /* Adjust DAYS and Y to match the guessed year. */ days -= ((yg - y) * 365 diff --git a/time/tzfile.c b/time/tzfile.c index 844a68d..3920525 100644 --- a/time/tzfile.c +++ b/time/tzfile.c @@ -633,16 +633,10 @@ __tzfile_compute (__time64_t timer, int use_localtime, /* Convert to broken down structure. If this fails do not use the string. */ - { - time_t truncated = timer; - if (__glibc_unlikely (truncated != timer - || ! __offtime (&truncated, 0, tp))) - goto use_last; - } - - /* Use the rules from the TZ string to compute the change. - timer fits into time_t due to the truncation check - above. */ + if (__glibc_unlikely (! __offtime (timer, 0, tp))) + goto use_last; + + /* Use the rules from the TZ string to compute the change. */ __tz_compute (timer, tp, 1); /* If tzspec comes from posixrules loaded by __tzfile_default, diff --git a/time/tzset.c b/time/tzset.c index a828b9f..834cc3c 100644 --- a/time/tzset.c +++ b/time/tzset.c @@ -16,7 +16,6 @@ <http://www.gnu.org/licenses/>. */ #include <ctype.h> -#include <errno.h> #include <libc-lock.h> #include <stdbool.h> #include <stddef.h> @@ -27,7 +26,7 @@ #include <timezone/tzfile.h> -#define SECSPERDAY ((time_t) 86400) +#define SECSPERDAY ((__time64_t) 86400) char *__tzname[2] = { (char *) "GMT", (char *) "GMT" }; int __daylight = 0; @@ -55,7 +54,7 @@ typedef struct /* We cache the computed time of change for a given year so we don't have to recompute it. */ - time_t change; /* When to change to this zone. */ + __time64_t change; /* When to change to this zone. */ int computed_for; /* Year above is computed for. */ } tz_rule; @@ -416,7 +415,7 @@ tzset_internal (int always) tz_rules[0].name = tz_rules[1].name = "UTC"; if (J0 != 0) tz_rules[0].type = tz_rules[1].type = J0; - tz_rules[0].change = tz_rules[1].change = (time_t) -1; + tz_rules[0].change = tz_rules[1].change = -1; update_vars (); return; } @@ -424,13 +423,13 @@ tzset_internal (int always) __tzset_parse_tz (tz); } -/* Figure out the exact time (as a time_t) in YEAR +/* Figure out the exact time (as a __time64_t) in YEAR when the change described by RULE will occur and put it in RULE->change, saving YEAR in RULE->computed_for. */ static void compute_change (tz_rule *rule, int year) { - time_t t; + __time64_t t; if (year != -1 && rule->computed_for == year) /* Operations on times in 2 BC will be slower. Oh well. */ @@ -516,7 +515,7 @@ compute_change (tz_rule *rule, int year) /* Figure out the correct timezone for TM and set `__tzname', `__timezone', and `__daylight' accordingly. */ void -__tz_compute (time_t timer, struct tm *tm, int use_localtime) +__tz_compute (__time64_t timer, struct tm *tm, int use_localtime) { compute_change (&tz_rules[0], 1900 + tm->tm_year); compute_change (&tz_rules[1], 1900 + tm->tm_year); @@ -562,20 +561,14 @@ __tzset (void) } weak_alias (__tzset, tzset) -/* Return the `struct tm' representation of *TIMER in the local timezone. +/* Return the `struct tm' representation of TIMER in the local timezone. Use local time if USE_LOCALTIME is nonzero, UTC otherwise. */ struct tm * -__tz_convert (const time_t *timer, int use_localtime, struct tm *tp) +__tz_convert (__time64_t timer, int use_localtime, struct tm *tp) { long int leap_correction; int leap_extra_secs; - if (timer == NULL) - { - __set_errno (EINVAL); - return NULL; - } - __libc_lock_lock (tzset_lock); /* Update internal database according to current TZ setting. @@ -584,14 +577,14 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp) tzset_internal (tp == &_tmbuf && use_localtime); if (__use_tzfile) - __tzfile_compute (*timer, use_localtime, &leap_correction, + __tzfile_compute (timer, use_localtime, &leap_correction, &leap_extra_secs, tp); else { if (! __offtime (timer, 0, tp)) tp = NULL; else - __tz_compute (*timer, tp, use_localtime); + __tz_compute (timer, tp, use_localtime); leap_correction = 0L; leap_extra_secs = 0; } |