From b6120a13a752335bc1c60d5d22a1cdb0b4403a7a Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 20 Jun 2018 11:37:54 -0700 Subject: [PATCH 2/2] difftime: new __time64_t variant * include/time.h (__difftime64): New macro or function decl. * time/difftime.c: Include "time-internal.h" if not glibc, for outside-glibc uses. (subtract, __difftime64) Use __time64_t, not time_t. (__difftime) [__TIMESIZAE != 64]: Turn into a wrapper function for __difftime64, a new function that contains the old body of __difftime. --- include/time.h | 6 ++++++ time/difftime.c | 36 ++++++++++++++++++++++++++---------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/include/time.h b/include/time.h index 5afb12305e..63cc855749 100644 --- a/include/time.h +++ b/include/time.h @@ -125,6 +125,12 @@ extern char * __strptime_internal (const char *rp, const char *fmt, struct tm *tm, void *statep, locale_t locparam) attribute_hidden; +#if __TIMESIZE == 64 +# define __difftime64 __difftime +#else +extern double __difftime64 (__time64_t time1, __time64_t time0); +#endif + extern double __difftime (time_t time1, time_t time0); /* Use in the clock_* functions. Size of the field representing the diff --git a/time/difftime.c b/time/difftime.c index 7727f5cdb5..4e765de624 100644 --- a/time/difftime.c +++ b/time/difftime.c @@ -23,19 +23,23 @@ #include #include +#ifndef _LIBC +# include "time-internal.h" +#endif + #define TYPE_BITS(type) (sizeof (type) * CHAR_BIT) #define TYPE_SIGNED(type) ((type) -1 < 0) /* Return the difference between TIME1 and TIME0, where TIME0 <= TIME1. */ static double -subtract (time_t time1, time_t time0) +subtract (__time64_t time1, __time64_t time0) { - if (! TYPE_SIGNED (time_t)) + if (! TYPE_SIGNED (__time64_t)) return time1 - time0; else { - /* Optimize the common special cases where time_t + /* Optimize the common special cases where __time64_t can be converted to uintmax_t without losing information. */ uintmax_t dt = (uintmax_t) time1 - (uintmax_t) time0; double delta = dt; @@ -43,7 +47,7 @@ subtract (time_t time1, time_t time0) if (UINTMAX_MAX / 2 < INTMAX_MAX) { /* This is a rare host where uintmax_t has padding bits, and possibly - information was lost when converting time_t to uintmax_t. + information was lost when converting __time64_t to uintmax_t. Check for overflow by comparing dt/2 to (time1/2 - time0/2). Overflow occurred if they differ by more than a small slop. Thanks to Clive D.W. Feather for detailed technical advice about @@ -74,9 +78,9 @@ subtract (time_t time1, time_t time0) 1 is unsigned in C, so it need not be compared to zero. */ uintmax_t hdt = dt / 2; - time_t ht1 = time1 / 2; - time_t ht0 = time0 / 2; - time_t dht = ht1 - ht0; + __time64_t ht1 = time1 / 2; + __time64_t ht0 = time0 / 2; + __time64_t dht = ht1 - ht0; if (2 < dht - hdt + 1) { @@ -97,17 +101,17 @@ subtract (time_t time1, time_t time0) /* Return the difference between TIME1 and TIME0. */ double -__difftime (time_t time1, time_t time0) +__difftime64 (__time64_t time1, __time64_t time0) { /* Convert to double and then subtract if no double-rounding error could result. */ - if (TYPE_BITS (time_t) <= DBL_MANT_DIG) + if (TYPE_BITS (__time64_t) <= DBL_MANT_DIG) return (double) time1 - (double) time0; /* Likewise for long double. */ - if (TYPE_BITS (time_t) <= LDBL_MANT_DIG) + if (TYPE_BITS (__time64_t) <= LDBL_MANT_DIG) return (long double) time1 - (long double) time0; /* Subtract the smaller integer from the larger, convert the difference to @@ -115,4 +119,16 @@ __difftime (time_t time1, time_t time0) return time1 < time0 ? - subtract (time0, time1) : subtract (time1, time0); } + +#if __TIMESIZE != 64 + +/* Return the difference between TIME1 and TIME0. */ +double +__difftime (time_t time1, time_t time0) +{ + return __difftime64 (time1, time0); +} + +#endif + strong_alias (__difftime, difftime) -- 2.17.1