mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
Make mktime etc. compatible with __time64_t
Keep these functions compatible with Gnulib while adding __time64_t support. The basic idea is to move private API declarations from include/time.h to time/mktime-internal.h, since the former file cannot easily be shared with Gnulib whereas the latter can. Also, do some other minor cleanup while in the neighborhood. * include/time.h: Include stdbool.h, time/mktime-internal.h. (__mktime_internal): Move this prototype to time/mktime-internal.h, since Gnulib needs it. (__localtime64_r, __gmtime64_r) [__TIMESIZE == 64]: Move these macros to time/mktime-internal.h, since Gnulib needs them. (__mktime64, __timegm64) [__TIMESIZE != 64]: New prototypes. (in_time_t_range): New static function. * posix/bits/types.h (__time64_t) [__TIMESIZE == 64 && !defined __LIBC]: Do not define as a macro in this case, so that portable code is less tempted to use __time64_t. * time/mktime-internal.h: Rewrite so that it does both glibc and Gnulib work. Include time.h if not _LIBC. (mktime_offset_t) [!_LIBC]: Define for gnulib. (__time64_t, __gmtime64_r, __localtime64_r, __mktime64, __timegm64) [!_LIBC || __TIMESIZE == 64]: New macros, mostly moved here from include/time.h. (__gmtime_r, __localtime_r, __mktime_internal) [!_LIBC]: New macros, taken from GNulib. (__mktime_internal): New prototype, moved here from include/time.h. * time/mktime.c (mktime_min, mktime_max, convert_time) (ranged_convert, __mktime_internal, __mktime64): * time/timegm.c (__timegm64): Use __time64_t, not time_t. * time/mktime.c: Stop worrying about whether time_t is floating-point. (__mktime64) [! (_LIBC && __TIMESIZE != 64)]: Rename from mktime. (mktime) [_LIBC && __TIMESIZE != 64]: New function. * time/timegm.c [!_LIBC]: Include libc-config.h, not config.h, for libc_hidden_def. Include errno.h. (__timegm64) [! (_LIBC && __TIMESIZE != 64)]: Rename from timegm. (timegm) [_LIBC && __TIMESIZE != 64]: New function. First cut at publicizing __time64_t
This commit is contained in:
44
ChangeLog
44
ChangeLog
@ -1,3 +1,47 @@
|
|||||||
|
2019-04-30 Paul Eggert <eggert@cs.ucla.edu>
|
||||||
|
|
||||||
|
Make mktime etc. compatible with __time64_t
|
||||||
|
Keep these functions compatible with Gnulib while adding
|
||||||
|
__time64_t support. The basic idea is to move private API
|
||||||
|
declarations from include/time.h to time/mktime-internal.h, since
|
||||||
|
the former file cannot easily be shared with Gnulib whereas the
|
||||||
|
latter can.
|
||||||
|
Also, do some other minor cleanup while in the neighborhood.
|
||||||
|
* include/time.h: Include stdbool.h, time/mktime-internal.h.
|
||||||
|
(__mktime_internal): Move this prototype to time/mktime-internal.h,
|
||||||
|
since Gnulib needs it.
|
||||||
|
(__localtime64_r, __gmtime64_r) [__TIMESIZE == 64]:
|
||||||
|
Move these macros to time/mktime-internal.h, since Gnulib needs them.
|
||||||
|
(__mktime64, __timegm64) [__TIMESIZE != 64]: New prototypes.
|
||||||
|
(in_time_t_range): New static function.
|
||||||
|
* posix/bits/types.h (__time64_t): Move to time/mktime-internal.h,
|
||||||
|
so that glibc users are not tempted to use __time64_t.
|
||||||
|
* time/mktime-internal.h: Rewrite so that it does both glibc
|
||||||
|
and Gnulib work. Include time.h if not _LIBC.
|
||||||
|
(mktime_offset_t) [!_LIBC]: Define for gnulib.
|
||||||
|
(__time64_t): New type or macro, moved here from
|
||||||
|
posix/bits/types.h.
|
||||||
|
(__gmtime64_r, __localtime64_r, __mktime64, __timegm64)
|
||||||
|
[!_LIBC || __TIMESIZE == 64): New macros, mostly moved here
|
||||||
|
from include/time.h.
|
||||||
|
(__gmtime_r, __localtime_r, __mktime_internal) [!_LIBC]:
|
||||||
|
New macros, taken from GNulib.
|
||||||
|
(__mktime_internal): New prototype, moved here from include/time.h.
|
||||||
|
* time/mktime.c (mktime_min, mktime_max, convert_time)
|
||||||
|
(ranged_convert, __mktime_internal, __mktime64):
|
||||||
|
* time/timegm.c (__timegm64):
|
||||||
|
Use __time64_t, not time_t.
|
||||||
|
* time/mktime.c: Stop worrying about whether time_t is floating-point.
|
||||||
|
(__mktime64) [! (_LIBC && __TIMESIZE != 64)]:
|
||||||
|
Rename from mktime.
|
||||||
|
(mktime) [_LIBC && __TIMESIZE != 64]: New function.
|
||||||
|
* time/timegm.c [!_LIBC]: Include libc-config.h, not config.h,
|
||||||
|
for libc_hidden_def.
|
||||||
|
Include errno.h.
|
||||||
|
(__timegm64) [! (_LIBC && __TIMESIZE != 64)]:
|
||||||
|
Rename from timegm.
|
||||||
|
(timegm) [_LIBC && __TIMESIZE != 64]: New function.
|
||||||
|
|
||||||
2019-04-30 Maciej W. Rozycki <macro@wdc.com>
|
2019-04-30 Maciej W. Rozycki <macro@wdc.com>
|
||||||
|
|
||||||
[BZ #19444]
|
[BZ #19444]
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#ifndef _ISOMAC
|
#ifndef _ISOMAC
|
||||||
# include <bits/types/locale_t.h>
|
# include <bits/types/locale_t.h>
|
||||||
|
# include <stdbool.h>
|
||||||
|
# include <time/mktime-internal.h>
|
||||||
|
|
||||||
extern __typeof (strftime_l) __strftime_l;
|
extern __typeof (strftime_l) __strftime_l;
|
||||||
libc_hidden_proto (__strftime_l)
|
libc_hidden_proto (__strftime_l)
|
||||||
@ -49,19 +51,11 @@ extern void __tzset_parse_tz (const char *tz) attribute_hidden;
|
|||||||
extern void __tz_compute (__time64_t timer, struct tm *tm, int use_localtime)
|
extern void __tz_compute (__time64_t timer, struct tm *tm, int use_localtime)
|
||||||
__THROW attribute_hidden;
|
__THROW attribute_hidden;
|
||||||
|
|
||||||
/* Subroutine of `mktime'. Return the `time_t' representation of TP and
|
|
||||||
normalize TP, given that a `struct tm *' maps to a `time_t' as performed
|
|
||||||
by FUNC. Record next guess for localtime-gmtime offset in *OFFSET. */
|
|
||||||
extern time_t __mktime_internal (struct tm *__tp,
|
|
||||||
struct tm *(*__func) (const time_t *,
|
|
||||||
struct tm *),
|
|
||||||
long int *__offset) attribute_hidden;
|
|
||||||
|
|
||||||
#if __TIMESIZE == 64
|
#if __TIMESIZE == 64
|
||||||
# define __ctime64 ctime
|
# define __ctime64 ctime
|
||||||
#else
|
#else
|
||||||
extern char *__ctime64 (const __time64_t *__timer) __THROW;
|
extern char *__ctime64 (const __time64_t *__timer) __THROW;
|
||||||
libc_hidden_proto (__ctime64);
|
libc_hidden_proto (__ctime64)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __TIMESIZE == 64
|
#if __TIMESIZE == 64
|
||||||
@ -69,7 +63,7 @@ libc_hidden_proto (__ctime64);
|
|||||||
#else
|
#else
|
||||||
extern char *__ctime64_r (const __time64_t *__restrict __timer,
|
extern char *__ctime64_r (const __time64_t *__restrict __timer,
|
||||||
char *__restrict __buf) __THROW;
|
char *__restrict __buf) __THROW;
|
||||||
libc_hidden_proto (__ctime64_r);
|
libc_hidden_proto (__ctime64_r)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __TIMESIZE == 64
|
#if __TIMESIZE == 64
|
||||||
@ -81,13 +75,13 @@ libc_hidden_proto (__localtime64)
|
|||||||
|
|
||||||
extern struct tm *__localtime_r (const time_t *__timer,
|
extern struct tm *__localtime_r (const time_t *__timer,
|
||||||
struct tm *__tp) attribute_hidden;
|
struct tm *__tp) attribute_hidden;
|
||||||
|
#if __TIMESIZE != 64
|
||||||
#if __TIMESIZE == 64
|
|
||||||
# define __localtime64_r __localtime_r
|
|
||||||
#else
|
|
||||||
extern struct tm *__localtime64_r (const __time64_t *__timer,
|
extern struct tm *__localtime64_r (const __time64_t *__timer,
|
||||||
struct tm *__tp);
|
struct tm *__tp);
|
||||||
libc_hidden_proto (__localtime64_r)
|
libc_hidden_proto (__localtime64_r)
|
||||||
|
|
||||||
|
extern __time64_t __mktime64 (struct tm *__tp) __THROW;
|
||||||
|
libc_hidden_proto (__mktime64)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern struct tm *__gmtime_r (const time_t *__restrict __timer,
|
extern struct tm *__gmtime_r (const time_t *__restrict __timer,
|
||||||
@ -99,14 +93,13 @@ libc_hidden_proto (__gmtime_r)
|
|||||||
#else
|
#else
|
||||||
extern struct tm *__gmtime64 (const __time64_t *__timer);
|
extern struct tm *__gmtime64 (const __time64_t *__timer);
|
||||||
libc_hidden_proto (__gmtime64)
|
libc_hidden_proto (__gmtime64)
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __TIMESIZE == 64
|
|
||||||
# define __gmtime64_r __gmtime_r
|
|
||||||
#else
|
|
||||||
extern struct tm *__gmtime64_r (const __time64_t *__restrict __timer,
|
extern struct tm *__gmtime64_r (const __time64_t *__restrict __timer,
|
||||||
struct tm *__restrict __tp);
|
struct tm *__restrict __tp);
|
||||||
libc_hidden_proto (__gmtime64_r);
|
libc_hidden_proto (__gmtime64_r)
|
||||||
|
|
||||||
|
extern __time64_t __timegm64 (struct tm *__tp) __THROW;
|
||||||
|
libc_hidden_proto (__timegm64)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Compute the `struct tm' representation of T,
|
/* Compute the `struct tm' representation of T,
|
||||||
@ -155,5 +148,13 @@ extern double __difftime (time_t time1, time_t time0);
|
|||||||
actual clock ID. */
|
actual clock ID. */
|
||||||
#define CLOCK_IDFIELD_SIZE 3
|
#define CLOCK_IDFIELD_SIZE 3
|
||||||
|
|
||||||
|
/* Check whether T fits in time_t. */
|
||||||
|
static inline bool
|
||||||
|
in_time_t_range (__time64_t t)
|
||||||
|
{
|
||||||
|
time_t s = t;
|
||||||
|
return s == t;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -213,10 +213,13 @@ __STD_TYPE __U32_TYPE __socklen_t;
|
|||||||
It is not currently necessary for this to be machine-specific. */
|
It is not currently necessary for this to be machine-specific. */
|
||||||
typedef int __sig_atomic_t;
|
typedef int __sig_atomic_t;
|
||||||
|
|
||||||
#if __TIMESIZE == 64
|
/* Seconds since the Epoch, visible to user code when time_t is too
|
||||||
|
narrow only for consistency with the old way of widening too-narrow
|
||||||
|
types. User code should never use __time64_t. */
|
||||||
|
#if __TIMESIZE == 64 && defined __LIBC
|
||||||
# define __time64_t __time_t
|
# define __time64_t __time_t
|
||||||
#else
|
#elif __TIMESIZE != 64
|
||||||
__STD_TYPE __TIME64_T_TYPE __time64_t; /* Seconds since the Epoch. */
|
__STD_TYPE __TIME64_T_TYPE __time64_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#undef __STD_TYPE
|
#undef __STD_TYPE
|
||||||
|
@ -1,2 +1,79 @@
|
|||||||
/* Gnulib mktime-internal.h, tailored for glibc. */
|
/* Internals of mktime and related functions
|
||||||
|
Copyright 2016-2019 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Paul Eggert <eggert@cs.ucla.edu>.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef _LIBC
|
||||||
|
# include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* mktime_offset_t is a signed type wide enough to hold a UTC offset
|
||||||
|
in seconds, and used as part of the type of the offset-guess
|
||||||
|
argument to mktime_internal. In Glibc, it is always long int.
|
||||||
|
When in Gnulib, use time_t on platforms where time_t
|
||||||
|
is signed, to be compatible with platforms like BeOS that export
|
||||||
|
this implementation detail of mktime. On platforms where time_t is
|
||||||
|
unsigned, GNU and POSIX code can assume 'int' is at least 32 bits
|
||||||
|
which is wide enough for a UTC offset. */
|
||||||
|
#ifdef _LIBC
|
||||||
typedef long int mktime_offset_t;
|
typedef long int mktime_offset_t;
|
||||||
|
#elif defined TIME_T_IS_SIGNED
|
||||||
|
typedef time_t mktime_offset_t;
|
||||||
|
#else
|
||||||
|
typedef int mktime_offset_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The source code uses identifiers like __time64_t for glibc
|
||||||
|
timestamps that can contain 64-bit values even when time_t is only
|
||||||
|
32 bits. These are just macros for the ordinary identifiers unless
|
||||||
|
compiling within glibc when time_t is 32 bits. */
|
||||||
|
#if ! (defined _LIBC && __TIMESIZE != 64)
|
||||||
|
# undef __time64_t
|
||||||
|
# define __time64_t time_t
|
||||||
|
# define __gmtime64_r __gmtime_r
|
||||||
|
# define __localtime64_r __localtime_r
|
||||||
|
# define __mktime64 mktime
|
||||||
|
# define __timegm64 timegm
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _LIBC
|
||||||
|
|
||||||
|
/* Although glibc source code uses leading underscores, Gnulib wants
|
||||||
|
ordinary names.
|
||||||
|
|
||||||
|
Portable standalone applications should supply a <time.h> that
|
||||||
|
declares a POSIX-compliant localtime_r, for the benefit of older
|
||||||
|
implementations that lack localtime_r or have a nonstandard one.
|
||||||
|
Similarly for gmtime_r. See the gnulib time_r module for one way
|
||||||
|
to implement this. */
|
||||||
|
|
||||||
|
# undef __gmtime_r
|
||||||
|
# undef __localtime_r
|
||||||
|
# define __gmtime_r gmtime_r
|
||||||
|
# define __localtime_r localtime_r
|
||||||
|
|
||||||
|
# define __mktime_internal mktime_internal
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Subroutine of mktime. Return the time_t representation of TP and
|
||||||
|
normalize TP, given that a struct tm * maps to a time_t as performed
|
||||||
|
by FUNC. Record next guess for localtime-gmtime offset in *OFFSET. */
|
||||||
|
extern __time64_t __mktime_internal (struct tm *tp,
|
||||||
|
struct tm *(*func) (__time64_t const *,
|
||||||
|
struct tm *),
|
||||||
|
mktime_offset_t *offset) attribute_hidden;
|
||||||
|
@ -112,11 +112,11 @@ my_tzset (void)
|
|||||||
added to them, and then with another timestamp added, without
|
added to them, and then with another timestamp added, without
|
||||||
worrying about overflow.
|
worrying about overflow.
|
||||||
|
|
||||||
Much of the code uses long_int to represent time_t values, to
|
Much of the code uses long_int to represent __time64_t values, to
|
||||||
lessen the hassle of dealing with platforms where time_t is
|
lessen the hassle of dealing with platforms where __time64_t is
|
||||||
unsigned, and because long_int should suffice to represent all
|
unsigned, and because long_int should suffice to represent all
|
||||||
time_t values that mktime can generate even on platforms where
|
__time64_t values that mktime can generate even on platforms where
|
||||||
time_t is excessively wide. */
|
__time64_t is wider than the int components of struct tm. */
|
||||||
|
|
||||||
#if INT_MAX <= LONG_MAX / 4 / 366 / 24 / 60 / 60
|
#if INT_MAX <= LONG_MAX / 4 / 366 / 24 / 60 / 60
|
||||||
typedef long int long_int;
|
typedef long int long_int;
|
||||||
@ -144,16 +144,15 @@ shr (long_int a, int b)
|
|||||||
: a / (one << b) - (a % (one << b) < 0));
|
: a / (one << b) - (a % (one << b) < 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bounds for the intersection of time_t and long_int. */
|
/* Bounds for the intersection of __time64_t and long_int. */
|
||||||
|
|
||||||
static long_int const mktime_min
|
static long_int const mktime_min
|
||||||
= ((TYPE_SIGNED (time_t) && TYPE_MINIMUM (time_t) < TYPE_MINIMUM (long_int))
|
= ((TYPE_SIGNED (__time64_t)
|
||||||
? TYPE_MINIMUM (long_int) : TYPE_MINIMUM (time_t));
|
&& TYPE_MINIMUM (__time64_t) < TYPE_MINIMUM (long_int))
|
||||||
|
? TYPE_MINIMUM (long_int) : TYPE_MINIMUM (__time64_t));
|
||||||
static long_int const mktime_max
|
static long_int const mktime_max
|
||||||
= (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (time_t)
|
= (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (__time64_t)
|
||||||
? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (time_t));
|
? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (__time64_t));
|
||||||
|
|
||||||
verify (TYPE_IS_INTEGER (time_t));
|
|
||||||
|
|
||||||
#define EPOCH_YEAR 1970
|
#define EPOCH_YEAR 1970
|
||||||
#define TM_YEAR_BASE 1900
|
#define TM_YEAR_BASE 1900
|
||||||
@ -252,23 +251,23 @@ tm_diff (long_int year, long_int yday, int hour, int min, int sec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Use CONVERT to convert T to a struct tm value in *TM. T must be in
|
/* Use CONVERT to convert T to a struct tm value in *TM. T must be in
|
||||||
range for time_t. Return TM if successful, NULL (setting errno) on
|
range for __time64_t. Return TM if successful, NULL (setting errno) on
|
||||||
failure. */
|
failure. */
|
||||||
static struct tm *
|
static struct tm *
|
||||||
convert_time (struct tm *(*convert) (const time_t *, struct tm *),
|
convert_time (struct tm *(*convert) (const __time64_t *, struct tm *),
|
||||||
long_int t, struct tm *tm)
|
long_int t, struct tm *tm)
|
||||||
{
|
{
|
||||||
time_t x = t;
|
__time64_t x = t;
|
||||||
return convert (&x, tm);
|
return convert (&x, tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use CONVERT to convert *T to a broken down time in *TP.
|
/* Use CONVERT to convert *T to a broken down time in *TP.
|
||||||
If *T is out of range for conversion, adjust it so that
|
If *T is out of range for conversion, adjust it so that
|
||||||
it is the nearest in-range value and then convert that.
|
it is the nearest in-range value and then convert that.
|
||||||
A value is in range if it fits in both time_t and long_int.
|
A value is in range if it fits in both __time64_t and long_int.
|
||||||
Return TP on success, NULL (setting errno) on failure. */
|
Return TP on success, NULL (setting errno) on failure. */
|
||||||
static struct tm *
|
static struct tm *
|
||||||
ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
|
ranged_convert (struct tm *(*convert) (const __time64_t *, struct tm *),
|
||||||
long_int *t, struct tm *tp)
|
long_int *t, struct tm *tp)
|
||||||
{
|
{
|
||||||
long_int t1 = (*t < mktime_min ? mktime_min
|
long_int t1 = (*t < mktime_min ? mktime_min
|
||||||
@ -310,7 +309,7 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Convert *TP to a time_t value, inverting
|
/* Convert *TP to a __time64_t value, inverting
|
||||||
the monotonic and mostly-unit-linear conversion function CONVERT.
|
the monotonic and mostly-unit-linear conversion function CONVERT.
|
||||||
Use *OFFSET to keep track of a guess at the offset of the result,
|
Use *OFFSET to keep track of a guess at the offset of the result,
|
||||||
compared to what the result would be for UTC without leap seconds.
|
compared to what the result would be for UTC without leap seconds.
|
||||||
@ -318,9 +317,9 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
|
|||||||
If successful, set *TP to the canonicalized struct tm;
|
If successful, set *TP to the canonicalized struct tm;
|
||||||
otherwise leave *TP alone, return ((time_t) -1) and set errno.
|
otherwise leave *TP alone, return ((time_t) -1) and set errno.
|
||||||
This function is external because it is used also by timegm.c. */
|
This function is external because it is used also by timegm.c. */
|
||||||
time_t
|
__time64_t
|
||||||
__mktime_internal (struct tm *tp,
|
__mktime_internal (struct tm *tp,
|
||||||
struct tm *(*convert) (const time_t *, struct tm *),
|
struct tm *(*convert) (const __time64_t *, struct tm *),
|
||||||
mktime_offset_t *offset)
|
mktime_offset_t *offset)
|
||||||
{
|
{
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
@ -520,9 +519,9 @@ __mktime_internal (struct tm *tp,
|
|||||||
|
|
||||||
#if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS
|
#if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS
|
||||||
|
|
||||||
/* Convert *TP to a time_t value. */
|
/* Convert *TP to a __time64_t value. */
|
||||||
time_t
|
__time64_t
|
||||||
mktime (struct tm *tp)
|
__mktime64 (struct tm *tp)
|
||||||
{
|
{
|
||||||
/* POSIX.1 8.1.1 requires that whenever mktime() is called, the
|
/* POSIX.1 8.1.1 requires that whenever mktime() is called, the
|
||||||
time zone names contained in the external variable 'tzname' shall
|
time zone names contained in the external variable 'tzname' shall
|
||||||
@ -531,7 +530,7 @@ mktime (struct tm *tp)
|
|||||||
|
|
||||||
# if defined _LIBC || NEED_MKTIME_WORKING
|
# if defined _LIBC || NEED_MKTIME_WORKING
|
||||||
static mktime_offset_t localtime_offset;
|
static mktime_offset_t localtime_offset;
|
||||||
return __mktime_internal (tp, __localtime_r, &localtime_offset);
|
return __mktime_internal (tp, __localtime64_r, &localtime_offset);
|
||||||
# else
|
# else
|
||||||
# undef mktime
|
# undef mktime
|
||||||
return mktime (tp);
|
return mktime (tp);
|
||||||
@ -539,11 +538,29 @@ mktime (struct tm *tp)
|
|||||||
}
|
}
|
||||||
#endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */
|
#endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */
|
||||||
|
|
||||||
#ifdef weak_alias
|
#if defined _LIBC && __TIMESIZE != 64
|
||||||
weak_alias (mktime, timelocal)
|
|
||||||
|
libc_hidden_def (__mktime64)
|
||||||
|
|
||||||
|
time_t
|
||||||
|
mktime (struct tm *tp)
|
||||||
|
{
|
||||||
|
struct tm tm = *tp;
|
||||||
|
__time64_t t = __mktime64 (&tm);
|
||||||
|
if (in_time_t_range (t))
|
||||||
|
{
|
||||||
|
*tp = tm;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
__set_errno (EOVERFLOW);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _LIBC
|
weak_alias (mktime, timelocal)
|
||||||
libc_hidden_def (mktime)
|
libc_hidden_def (mktime)
|
||||||
libc_hidden_weak (timelocal)
|
libc_hidden_weak (timelocal)
|
||||||
#endif
|
|
||||||
|
@ -18,17 +18,41 @@
|
|||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#ifndef _LIBC
|
#ifndef _LIBC
|
||||||
# include <config.h>
|
# include <libc-config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "mktime-internal.h"
|
#include "mktime-internal.h"
|
||||||
|
|
||||||
|
__time64_t
|
||||||
|
__timegm64 (struct tm *tmp)
|
||||||
|
{
|
||||||
|
static mktime_offset_t gmtime_offset;
|
||||||
|
tmp->tm_isdst = 0;
|
||||||
|
return __mktime_internal (tmp, __gmtime64_r, &gmtime_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined _LIBC && __TIMESIZE != 64
|
||||||
|
|
||||||
|
libc_hidden_def (__timegm64)
|
||||||
|
|
||||||
time_t
|
time_t
|
||||||
timegm (struct tm *tmp)
|
timegm (struct tm *tmp)
|
||||||
{
|
{
|
||||||
static mktime_offset_t gmtime_offset;
|
struct tm tm = *tmp;
|
||||||
tmp->tm_isdst = 0;
|
__time64_t t = __timegm64 (&tm);
|
||||||
return __mktime_internal (tmp, __gmtime_r, &gmtime_offset);
|
if (in_time_t_range (t))
|
||||||
|
{
|
||||||
|
*tmp = tm;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
__set_errno (EOVERFLOW);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
Reference in New Issue
Block a user