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


Reply via email to