2025-01-04 Paul Eggert <eggert@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.
# 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)
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. */
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
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)
{
__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 */