Message ID | 20181220204041.9377-1-albert.aribaud@3adev.fr |
---|---|

State | New |

Headers | show |

This version is OK.

On Thu, Dec 20, 2018 at 12:40 PM Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> wrote: > > Provide a 64-bit-time version of __difftime (but do not assume > __time64_t is a signed int so that Gnulib can reuse the code) > and make the 32-bit version a wrapper of it. > > Current difftime expects two time_t arguments and returns a > double. To preserve source-code compatibility, its 64-bit-time > equivalent expects two __time64_t arguments but still returns > a double. > > This patch was tested by running 'make check' on branch > master then applying this patch and its two predecessors and > running 'make check' again, and checking that both 'make check' > yield identical results. This was done on x86_64-linux-gnu and > i686-linux-gnu. > > This patch was also functionally tested with an ad hoc userland > C program which checks the result of difftime for various pairs > of 32-bit and, for 64-bit builds, of 64-bit time_t values too. > The program was built and run against a glibc with and without > the patch, and the results compared to ensure the patch does > not change the behavior of difftime. > > * include/time.h (__difftime64): Add. > * time/difftime.c (subtract): convert to 64-bit time. > * time/difftime.c (__difftime64): Add. > * time/difftime.c (__difftime): Wrap around __difftime64. > --- This caused: https://sourceware.org/bugzilla/show_bug.cgi?id=24023

diff --git a/include/time.h b/include/time.h index a10a59a628..f935e9dd3e 100644 --- a/include/time.h +++ b/include/time.h @@ -141,6 +141,13 @@ 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); +libc_hidden_proto (__difftime64) +#endif + extern double __difftime (time_t time1, time_t time0); diff --git a/time/difftime.c b/time/difftime.c index 7c5dd9898b..5243cbd9cb 100644 --- a/time/difftime.c +++ b/time/difftime.c @@ -31,9 +31,9 @@ time_t is known to be an integer type. */ 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 { @@ -76,9 +76,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) { @@ -99,18 +99,18 @@ 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 - || (TYPE_FLOATING (time_t) && sizeof (time_t) < sizeof (long double))) + if (TYPE_BITS (__time64_t) <= DBL_MANT_DIG + || (TYPE_FLOATING (__time64_t) && sizeof (__time64_t) < sizeof (long double))) return (double) time1 - (double) time0; /* Likewise for long double. */ - if (TYPE_BITS (time_t) <= LDBL_MANT_DIG || TYPE_FLOATING (time_t)) + if (TYPE_BITS (__time64_t) <= LDBL_MANT_DIG || TYPE_FLOATING (__time64_t)) return (long double) time1 - (long double) time0; /* Subtract the smaller integer from the larger, convert the difference to @@ -118,4 +118,20 @@ __difftime (time_t time1, time_t time0) return time1 < time0 ? - subtract (time0, time1) : subtract (time1, time0); } + +/* Provide a 32-bit wrapper if needed. */ + +#if __TIMESIZE != 64 + +libc_hidden_def (__difftime64) + +double +__difftime (time_t time1, time_t time0) +{ + return __difftime64 (time1, time0); +} + +#endif + strong_alias (__difftime, difftime) +