From patchwork Wed Jun 13 07:00:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Albert ARIBAUD (3ADEV)" X-Patchwork-Id: 928708 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-93132-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=3adev.fr Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="sLkjkxyR"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 415HjG5xhFz9s19 for ; Wed, 13 Jun 2018 17:01:22 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=nSwboRncSt8PSAaVIn3xFz1Zouq551Z OwQEcnmQll32w8+ez0PKyaybSDGxyFB5DbliJj7kJeCAPGuxlX0jy3FT8L8UUPIa /ndy8xfWbzwdW4RW8vr+oVfV17S3s10eFvy59N4QXP/S9Z+9shHwCe1i/GKEglyK 3vDpf8e5IQvg= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references; s=default; bh=0+SBFEJLjLWB+gb25TPUj16E0C8=; b=sLkjk xyRrRtoxYiOaYec81Rv2853A0rS6UDA7khOdxun8WqOAH7/KFchlpzWin1vyNeDc uYLLYCVCgt+6nKpTd9q+nLIyYoCHIQmUONrg8rUiGi9wQMD5viaRJbolhhtav/v/ Pt5BaQsTq4RhvYhR5hfzVw20WVxpnmH9xig1OQ= Received: (qmail 2975 invoked by alias); 13 Jun 2018 07:00:56 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 2483 invoked by uid 89); 13 Jun 2018 07:00:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-23.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW, RCVD_IN_RP_RNBL autolearn=ham version=3.3.2 spammy=Epoch, epoch X-HELO: smtp4-g21.free.fr From: "Albert ARIBAUD (3ADEV)" To: libc-alpha@sourceware.org Cc: "Albert ARIBAUD (3ADEV)" Subject: [PATCH 1/2] Y2038: add type __time64_t Date: Wed, 13 Jun 2018 09:00:18 +0200 Message-Id: <20180613070019.4639-2-albert.aribaud@3adev.fr> In-Reply-To: <20180613070019.4639-1-albert.aribaud@3adev.fr> References: <20180613070019.4639-1-albert.aribaud@3adev.fr> This type is public, so that time_t can be a typedef of it when we switch the public API to 64-bit time. Also, provide a function to check if a __time64_t value fits in a (32-bit) __time_t. --- bits/typesizes.h | 1 + include/time.h | 9 ++++++++- posix/bits/types.h | 3 ++- sysdeps/mach/hurd/bits/typesizes.h | 1 + sysdeps/unix/sysv/linux/alpha/bits/typesizes.h | 1 + sysdeps/unix/sysv/linux/generic/bits/typesizes.h | 1 + sysdeps/unix/sysv/linux/s390/bits/typesizes.h | 1 + sysdeps/unix/sysv/linux/sparc/bits/typesizes.h | 1 + sysdeps/unix/sysv/linux/x86/bits/typesizes.h | 1 + 9 files changed, 17 insertions(+), 2 deletions(-) diff --git a/bits/typesizes.h b/bits/typesizes.h index 85eacf2518..0b6a19c230 100644 --- a/bits/typesizes.h +++ b/bits/typesizes.h @@ -48,6 +48,7 @@ #define __ID_T_TYPE __U32_TYPE #define __CLOCK_T_TYPE __SLONGWORD_TYPE #define __TIME_T_TYPE __SLONGWORD_TYPE +#define __TIME64_T_TYPE __SQUAD_TYPE #define __USECONDS_T_TYPE __U32_TYPE #define __SUSECONDS_T_TYPE __SLONGWORD_TYPE #define __DADDR_T_TYPE __S32_TYPE diff --git a/include/time.h b/include/time.h index 23d2580528..93638aa215 100644 --- a/include/time.h +++ b/include/time.h @@ -3,6 +3,7 @@ #ifndef _ISOMAC # include +# include extern __typeof (strftime_l) __strftime_l; libc_hidden_proto (__strftime_l) @@ -101,10 +102,16 @@ extern char * __strptime_internal (const char *rp, const char *fmt, extern double __difftime (time_t time1, time_t time0); - /* Use in the clock_* functions. Size of the field representing the actual clock ID. */ #define CLOCK_IDFIELD_SIZE 3 +/* check whether a time64_t value fits in a time_t */ +static inline bool +fits_in_time_t (__time64_t t) +{ + return t == (time_t) t; +} + #endif #endif diff --git a/posix/bits/types.h b/posix/bits/types.h index 5e22ce41bf..4c6553a266 100644 --- a/posix/bits/types.h +++ b/posix/bits/types.h @@ -155,7 +155,8 @@ __STD_TYPE __CLOCK_T_TYPE __clock_t; /* Type of CPU usage counts. */ __STD_TYPE __RLIM_T_TYPE __rlim_t; /* Type for resource measurement. */ __STD_TYPE __RLIM64_T_TYPE __rlim64_t; /* Type for resource measurement (LFS). */ __STD_TYPE __ID_T_TYPE __id_t; /* General type for IDs. */ -__STD_TYPE __TIME_T_TYPE __time_t; /* Seconds since the Epoch. */ +__STD_TYPE __TIME_T_TYPE __time_t; /* Seconds since the Epoch, Y2038-unsafe. */ +__STD_TYPE __TIME64_T_TYPE __time64_t; /* Seconds since the Epoch, Y2038-safe. */ __STD_TYPE __USECONDS_T_TYPE __useconds_t; /* Count of microseconds. */ __STD_TYPE __SUSECONDS_T_TYPE __suseconds_t; /* Signed count of microseconds. */ diff --git a/sysdeps/mach/hurd/bits/typesizes.h b/sysdeps/mach/hurd/bits/typesizes.h index d3026ba66e..c9dbe2bf33 100644 --- a/sysdeps/mach/hurd/bits/typesizes.h +++ b/sysdeps/mach/hurd/bits/typesizes.h @@ -48,6 +48,7 @@ #define __ID_T_TYPE __U32_TYPE #define __CLOCK_T_TYPE __SLONGWORD_TYPE #define __TIME_T_TYPE __SLONGWORD_TYPE +#define __TIME64_T_TYPE __SQUAD_TYPE #define __USECONDS_T_TYPE __U32_TYPE #define __SUSECONDS_T_TYPE __SLONGWORD_TYPE #define __DADDR_T_TYPE __S32_TYPE diff --git a/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h b/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h index d9a0b0467c..47b1e36165 100644 --- a/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h +++ b/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h @@ -47,6 +47,7 @@ #define __ID_T_TYPE __U32_TYPE #define __CLOCK_T_TYPE __SLONGWORD_TYPE #define __TIME_T_TYPE __SLONGWORD_TYPE +#define __TIME64_T_TYPE __SQUAD_TYPE #define __USECONDS_T_TYPE __U32_TYPE #define __SUSECONDS_T_TYPE __S64_TYPE #define __DADDR_T_TYPE __S32_TYPE diff --git a/sysdeps/unix/sysv/linux/generic/bits/typesizes.h b/sysdeps/unix/sysv/linux/generic/bits/typesizes.h index a2cb3433bf..db03b1ae8b 100644 --- a/sysdeps/unix/sysv/linux/generic/bits/typesizes.h +++ b/sysdeps/unix/sysv/linux/generic/bits/typesizes.h @@ -49,6 +49,7 @@ #define __ID_T_TYPE __U32_TYPE #define __CLOCK_T_TYPE __SLONGWORD_TYPE #define __TIME_T_TYPE __SLONGWORD_TYPE +#define __TIME64_T_TYPE __SQUAD_TYPE #define __USECONDS_T_TYPE __U32_TYPE #define __SUSECONDS_T_TYPE __SLONGWORD_TYPE #define __DADDR_T_TYPE __S32_TYPE diff --git a/sysdeps/unix/sysv/linux/s390/bits/typesizes.h b/sysdeps/unix/sysv/linux/s390/bits/typesizes.h index fdaa421958..138c6d6d10 100644 --- a/sysdeps/unix/sysv/linux/s390/bits/typesizes.h +++ b/sysdeps/unix/sysv/linux/s390/bits/typesizes.h @@ -48,6 +48,7 @@ #define __ID_T_TYPE __U32_TYPE #define __CLOCK_T_TYPE __SLONGWORD_TYPE #define __TIME_T_TYPE __SLONGWORD_TYPE +#define __TIME64_T_TYPE __SQUAD_TYPE #define __USECONDS_T_TYPE __U32_TYPE #define __SUSECONDS_T_TYPE __SLONGWORD_TYPE #define __DADDR_T_TYPE __S32_TYPE diff --git a/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h b/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h index b59f2ced75..5d6fb00a93 100644 --- a/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h +++ b/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h @@ -48,6 +48,7 @@ #define __ID_T_TYPE __U32_TYPE #define __CLOCK_T_TYPE __SLONGWORD_TYPE #define __TIME_T_TYPE __SLONGWORD_TYPE +#define __TIME64_T_TYPE __SQUAD_TYPE #define __USECONDS_T_TYPE __U32_TYPE #define __SUSECONDS_T_TYPE __S32_TYPE #define __DADDR_T_TYPE __S32_TYPE diff --git a/sysdeps/unix/sysv/linux/x86/bits/typesizes.h b/sysdeps/unix/sysv/linux/x86/bits/typesizes.h index e6f7481a19..f5d792d8f3 100644 --- a/sysdeps/unix/sysv/linux/x86/bits/typesizes.h +++ b/sysdeps/unix/sysv/linux/x86/bits/typesizes.h @@ -62,6 +62,7 @@ #define __ID_T_TYPE __U32_TYPE #define __CLOCK_T_TYPE __SYSCALL_SLONG_TYPE #define __TIME_T_TYPE __SYSCALL_SLONG_TYPE +#define __TIME64_T_TYPE __SQUAD_TYPE #define __USECONDS_T_TYPE __U32_TYPE #define __SUSECONDS_T_TYPE __SYSCALL_SLONG_TYPE #define __DADDR_T_TYPE __S32_TYPE From patchwork Wed Jun 13 07:00:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Albert ARIBAUD (3ADEV)" X-Patchwork-Id: 928707 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-93131-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=3adev.fr Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="CxB6xPQS"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 415Hj15mWNz9s47 for ; Wed, 13 Jun 2018 17:01:09 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=ccfktwqdY/PgRfO6nwUEI1BZBe2uy5h CaO+JVZa4y+ow+GWCO++xBPUpbrIuyWiiRA04qSqiviq2jfT1rIuCw4xYoq33Qeq m9u5g3wywyf6sDop26aIuLCh7jhtM/8B4tfrfZIBuItjO+fijceIZFuQ8wTMjJ8x TZ7CmHlp1W4Y= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references; s=default; bh=YxehAc/rskmIuMqcvbbjJRTwGZ8=; b=CxB6x PQSraWAjlMzUnGqTxHTdLkKGtX8U0dQ27M+uOj3v+Vl1W7jN0P24r2z48a+BoW17 Senp67VTFR/bX94P3KhnxKR3s0Y9bJFBd8dlEG/D2bKnhHAYAYgMvVVzviEr85sB aNezAdj5V3TzsG0OyoNBkO2eeqKTNfGWWwlLpE= Received: (qmail 2793 invoked by alias); 13 Jun 2018 07:00:55 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 2551 invoked by uid 89); 13 Jun 2018 07:00:36 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-23.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_RP_RNBL autolearn=ham version=3.3.2 spammy=Operations, DAYS, guessed, 1749 X-HELO: smtp4-g21.free.fr From: "Albert ARIBAUD (3ADEV)" To: libc-alpha@sourceware.org Cc: "Albert ARIBAUD (3ADEV)" Subject: [PATCH 2/2] Y2038: make __tz_convert compatible with 64-bit-time Date: Wed, 13 Jun 2018 09:00:19 +0200 Message-Id: <20180613070019.4639-3-albert.aribaud@3adev.fr> In-Reply-To: <20180613070019.4639-1-albert.aribaud@3adev.fr> References: <20180613070019.4639-1-albert.aribaud@3adev.fr> This implies that its callers be 64-bit-time compatible too. It is done by creating 64-bit-time versions of these and turning their original 32-bit-time versions into wrappers (at a slight execution time cost). The callers affected are: * localtime * localtime_r * ctime * ctime_r * gmtime * gmtime_r Note that in time/tzfile.c we do not need to check for time_t overflows anymore as introduced by commit fc79706a323 since we now use internal_time_t. --- include/time.h | 20 +++++++++++++++----- time/Versions | 5 +++++ time/ctime.c | 21 ++++++++++++++++++--- time/ctime_r.c | 21 ++++++++++++++++++--- time/gmtime.c | 38 +++++++++++++++++++++++++++++++++----- time/localtime.c | 36 ++++++++++++++++++++++++++++++++---- time/offtime.c | 12 ++++++------ time/tzfile.c | 14 ++++---------- time/tzset.c | 30 ++++++++++++------------------ 9 files changed, 143 insertions(+), 54 deletions(-) diff --git a/include/time.h b/include/time.h index 93638aa215..c67e163eb8 100644 --- a/include/time.h +++ b/include/time.h @@ -9,6 +9,8 @@ extern __typeof (strftime_l) __strftime_l; libc_hidden_proto (__strftime_l) extern __typeof (strptime_l) __strptime_l; +extern struct tm *__localtime64 (const __time64_t *__timer); + libc_hidden_proto (time) libc_hidden_proto (asctime) libc_hidden_proto (mktime) @@ -17,6 +19,8 @@ libc_hidden_proto (localtime) libc_hidden_proto (strftime) libc_hidden_proto (strptime) +libc_hidden_proto (__localtime64) + extern __typeof (clock_getres) __clock_getres; extern __typeof (clock_gettime) __clock_gettime; libc_hidden_proto (__clock_gettime) @@ -51,7 +55,7 @@ extern void __tzfile_default (const char *std, const char *dst, long int stdoff, long int dstoff) attribute_hidden; extern void __tzset_parse_tz (const char *tz) attribute_hidden; -extern void __tz_compute (time_t timer, struct tm *tm, int use_localtime) +extern void __tz_compute (internal_time_t timer, struct tm *tm, int use_localtime) __THROW attribute_hidden; /* Subroutine of `mktime'. Return the `time_t' representation of TP and @@ -64,15 +68,21 @@ extern time_t __mktime_internal (struct tm *__tp, extern struct tm *__localtime_r (const time_t *__timer, struct tm *__tp) attribute_hidden; +extern struct tm *__localtime64_r (const __time64_t *__timer, + struct tm *__tp) attribute_hidden; + extern struct tm *__gmtime_r (const time_t *__restrict __timer, struct tm *__restrict __tp); libc_hidden_proto (__gmtime_r) -/* Compute the `struct tm' representation of *T, +extern struct tm *__gmtime64_r (const __time64_t *__restrict __timer, + struct tm *__restrict __tp); + +/* 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. */ -extern int __offtime (const time_t *__timer, +extern int __offtime (const internal_time_t __timer, long int __offset, struct tm *__tp) attribute_hidden; @@ -81,8 +91,8 @@ extern char *__asctime_r (const struct tm *__tp, char *__buf) extern void __tzset (void) attribute_hidden; /* Prototype for the internal function to get information based on TZ. */ -extern struct tm *__tz_convert (const time_t *timer, int use_localtime, - struct tm *tp) attribute_hidden; +extern struct tm *__tz_convert (const internal_time_t timer, int use_localtime, + struct tm *tp) attribute_hidden; extern int __nanosleep (const struct timespec *__requested_time, struct timespec *__remaining); diff --git a/time/Versions b/time/Versions index fd838181e4..8b83f5b041 100644 --- a/time/Versions +++ b/time/Versions @@ -65,4 +65,9 @@ libc { GLIBC_2.16 { timespec_get; } + GLIBC_2.28 { + __ctime64; __ctime64_r; + __gmtime64; __gmtime64_r; + __localtime64; __localtime64_r; + } } diff --git a/time/ctime.c b/time/ctime.c index 1222614f29..de7f3c5bd3 100644 --- a/time/ctime.c +++ b/time/ctime.c @@ -16,13 +16,28 @@ . */ #include +#include /* Return a string as returned by asctime which is the representation of *T in that form. */ char * +__ctime64 (const __time64_t *t) +{ + /* Apply the same rule as ctime: + make ctime64 (t) is equivalent to asctime (localtime64 (t)). */ + return asctime (__localtime64 (t)); +} + +/* The 32-bit time wrapper. */ +char * ctime (const time_t *t) { - /* The C Standard says ctime (t) is equivalent to asctime (localtime (t)). - In particular, ctime and asctime must yield the same pointer. */ - return asctime (localtime (t)); + __time64_t t64; + if (t == NULL) + { + __set_errno (EINVAL); + return NULL; + } + t64 = *t; + return __ctime64 (&t64); } diff --git a/time/ctime_r.c b/time/ctime_r.c index c111146d76..eb6e2f3ed6 100644 --- a/time/ctime_r.c +++ b/time/ctime_r.c @@ -18,12 +18,27 @@ . */ #include +#include /* Return a string as returned by asctime which is the representation - of *T in that form. Reentrant version. */ + of *T in that form. Reentrant Y2038-proof version. */ char * -ctime_r (const time_t *t, char *buf) +__ctime64_r (const __time64_t *t, char *buf) { struct tm tm; - return __asctime_r (__localtime_r (t, &tm), buf); + return __asctime_r (__localtime64_r (t, &tm), buf); +} + +/* The 32-bit-time wrapper. */ +char * +ctime_r (const time_t *t, char *buf) +{ + __time64_t t64; + if (t == NULL) + { + __set_errno (EINVAL); + return NULL; + } + t64 = *t; + return __ctime64_r (&t64, buf); } diff --git a/time/gmtime.c b/time/gmtime.c index dc33b3e68a..b5ec84f36a 100644 --- a/time/gmtime.c +++ b/time/gmtime.c @@ -17,21 +17,49 @@ . */ #include +#include -/* Return the `struct tm' representation of *T in UTC, - using *TP to store the result. */ +/* Return the `struct tm' representation of 64-bit-time *T + in UTC, using *TP to store the result. */ +struct tm * +__gmtime64_r (const __time64_t *t, struct tm *tp) +{ + return __tz_convert (*t, 0, tp); +} + +/* The 32-bit-time wrapper. */ struct tm * __gmtime_r (const time_t *t, struct tm *tp) { - return __tz_convert (t, 0, tp); + __time64_t t64; + if (t == NULL) + { + __set_errno (EINVAL); + return NULL; + } + t64 = *t; + return __gmtime64_r (&t64, tp); } libc_hidden_def (__gmtime_r) weak_alias (__gmtime_r, gmtime_r) +/* Return the `struct tm' representation of 64-bit-time *T in UTC. */ +struct tm * +__gmtime64 (const __time64_t *t) +{ + return __tz_convert (*t, 0, &_tmbuf); +} -/* Return the `struct tm' representation of *T in UTC. */ +/* The 32-bit-time wrapper. */ struct tm * gmtime (const time_t *t) { - return __tz_convert (t, 0, &_tmbuf); + __time64_t t64; + if (t == NULL) + { + __set_errno (EINVAL); + return NULL; + } + t64 = *t; + return __gmtime64 (&t64); } diff --git a/time/localtime.c b/time/localtime.c index 8684a8a971..68f5322b21 100644 --- a/time/localtime.c +++ b/time/localtime.c @@ -17,25 +17,53 @@ . */ #include +#include /* The C Standard says that localtime and gmtime return the same pointer. */ struct tm _tmbuf; - /* Return the `struct tm' representation of *T in local time, using *TP to store the result. */ struct tm * +__localtime64_r (const __time64_t *t, struct tm *tp) +{ + return __tz_convert (*t, 1, tp); +} + +/* The 32-bit-time wrapper. */ +struct tm * __localtime_r (const time_t *t, struct tm *tp) { - return __tz_convert (t, 1, tp); + __time64_t t64; + if (t == NULL) + { + __set_errno (EINVAL); + return NULL; + } + t64 = *t; + return __localtime64_r (&t64, tp); } weak_alias (__localtime_r, localtime_r) - /* Return the `struct tm' representation of *T in local time. */ struct tm * +__localtime64 (const __time64_t *t) +{ + return __tz_convert (*t, 1, &_tmbuf); +} + +/* The 32-bit-time wrapper. */ +struct tm * localtime (const time_t *t) { - return __tz_convert (t, 1, &_tmbuf); + __time64_t t64; + if (t == NULL) + { + __set_errno (EINVAL); + return NULL; + } + t64 = *t; + return __localtime64 (&t64); } libc_hidden_def (localtime) + diff --git a/time/offtime.c b/time/offtime.c index 04c48389fc..1ff71e3c7e 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 (const internal_time_t t, long int offset, struct tm *tp) { - time_t days, rem, y; + internal_time_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); + internal_time_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 2a385b92bc..94ca3323d5 100644 --- a/time/tzfile.c +++ b/time/tzfile.c @@ -635,16 +635,10 @@ __tzfile_compute (internal_time_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 a828b9fb75..c2bb6cdffa 100644 --- a/time/tzset.c +++ b/time/tzset.c @@ -16,7 +16,6 @@ . */ #include -#include #include #include #include @@ -27,7 +26,7 @@ #include -#define SECSPERDAY ((time_t) 86400) +#define SECSPERDAY ((internal_time_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. */ + internal_time_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 = (internal_time_t) -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 an internal_time_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; + internal_time_t t; if (year != -1 && rule->computed_for == year) /* Operations on times in 2 BC will be slower. Oh well. */ @@ -514,9 +513,10 @@ compute_change (tz_rule *rule, int year) /* Figure out the correct timezone for TM and set `__tzname', - `__timezone', and `__daylight' accordingly. */ + `__timezone', and `__daylight' accordingly. + NOTE: this takes an internal_time_t value, so passing a __time_t value is OK. */ void -__tz_compute (time_t timer, struct tm *tm, int use_localtime) +__tz_compute (internal_time_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 +562,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 (const internal_time_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 +578,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; }