This is part of my attempt to merge glibc and gnulib mktime.c. It should not affect Gnulib-using code. * lib/mktime.c [_LIBC]: Include <tzset.h>. (convert_time, __tz_convert) [_LIBC]: Omit definitions, since glibc supplies __tz_convert internally. (__mktime64) [_LIBC]: Lock __tzset_lock while running. --- ChangeLog | 8 ++++++++ lib/mktime.c | 29 ++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/ChangeLog b/ChangeLog index 335a97d8cb..b3c6e48e6d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2025-01-04 Paul Eggert <egg...@cs.ucla.edu> + mktime: support glibc locking + This is part of my attempt to merge glibc and gnulib mktime.c. + It should not affect Gnulib-using code. + * lib/mktime.c [_LIBC]: Include <tzset.h>. + (convert_time, __tz_convert) [_LIBC]: Omit definitions, + since glibc supplies __tz_convert internally. + (__mktime64) [_LIBC]: Lock __tzset_lock while running. + mktime: prefer bool to int * lib/mktime.c (__mktime_internal): Use bool for a boolean local. diff --git a/lib/mktime.c b/lib/mktime.c index 75b5ef7eec..99f014c6bd 100644 --- a/lib/mktime.c +++ b/lib/mktime.c @@ -62,6 +62,9 @@ # define NEED_MKTIME_WORKING 0 #endif +#ifdef _LIBC +# include <tzset.h> +#endif #include "mktime-internal.h" #if !defined _LIBC && (NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS) @@ -250,6 +253,7 @@ tm_diff (long_int year, long_int yday, int hour, int min, int sec, tp->tm_hour, tp->tm_min, tp->tm_sec); } +#ifndef _LIBC /* Convert T to a struct tm value in *TM. Use localtime64_r if LOCAL, otherwise gmtime64_r. T must be in range for __time64_t. Return TM if successful, NULL (setting errno) on failure. */ @@ -262,8 +266,8 @@ convert_time (long_int t, bool local, struct tm *tm) else return __gmtime64_r (&x, tm); } -/* Call it __tzconvert to sync with other parts of glibc. */ -#define __tz_convert convert_time +# define __tz_convert convert_time +#endif /* Convert *T to a broken down time in *TP (as if by localtime if LOCAL, otherwise as if by gmtime). If *T is out of range for @@ -320,7 +324,9 @@ ranged_convert (bool local, long_int *t, struct tm *tp) If *OFFSET's guess is correct, only one reverse mapping call is needed. If successful, set *TP to the canonicalized struct tm; 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. + + If _LIBC, the caller must lock __tzset_lock. */ __time64_t __mktime_internal (struct tm *tp, bool local, mktime_offset_t *offset) { @@ -548,17 +554,26 @@ __mktime_internal (struct tm *tp, bool local, mktime_offset_t *offset) __time64_t __mktime64 (struct tm *tp) { - /* POSIX.1 requires mktime to set external variables like 'tzname' - as though tzset had been called. */ +# ifdef _LIBC + __libc_lock_lock (__tzset_lock); + __tzset_unlocked (); +# else __tzset (); +# endif # if defined _LIBC || NEED_MKTIME_WORKING static mktime_offset_t localtime_offset; - return __mktime_internal (tp, true, &localtime_offset); + __time64_t result = __mktime_internal (tp, true, &localtime_offset); # else # undef mktime - return mktime (tp); + __time64_t result = mktime (tp); +# endif + +# ifdef _LIBC + __libc_lock_unlock (__tzset_lock); # endif + + return result; } #endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */ -- 2.45.2