This is consistent with bleeding-edge TZDB and with POSIX 'free'.
* lib/time.in.h (tzfree) [!HAVE_TZALLOC]: Replace tzfree.
I suspect Android and NetBSD (the major implementations) don’t
always preserve errno, and it’s easier to replace tzfree everywhere.
* lib/time_rz.c: Always include errno.h.
(tzfree) [HAVE_TZALLOC]: New replacement function.
(set_tz): Do not bother to save and restore errno,
now that tzfree preserves errno.
* modules/time_rz (Depends-on): Add free-posix.
(configure.ac, Makefile.am): Always compile time_rz.c.
---
 ChangeLog       | 14 ++++++++++++++
 lib/time.in.h   |  9 ++++++++-
 lib/time_rz.c   | 18 ++++++++++++++----
 m4/time_rz.m4   |  5 +++--
 modules/time_rz |  5 +----
 5 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 76903f733f..940ebffb52 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2025-11-04  Paul Eggert  <[email protected]>
+
+       time_rz: tzfree now preserves errno
+       This is consistent with bleeding-edge TZDB and with POSIX 'free'.
+       * lib/time.in.h (tzfree) [!HAVE_TZALLOC]: Replace tzfree.
+       I suspect Android and NetBSD (the major implementations) don’t
+       always preserve errno, and it’s easier to replace tzfree everywhere.
+       * lib/time_rz.c: Always include errno.h.
+       (tzfree) [HAVE_TZALLOC]: New replacement function.
+       (set_tz): Do not bother to save and restore errno,
+       now that tzfree preserves errno.
+       * modules/time_rz (Depends-on): Add free-posix.
+       (configure.ac, Makefile.am): Always compile time_rz.c.
+
 2025-11-02  Paul Eggert  <[email protected]>
 
        fchmodat: don’t depend on openat
diff --git a/lib/time.in.h b/lib/time.in.h
index 3ff16e3b3e..d28702d2f6 100644
--- a/lib/time.in.h
+++ b/lib/time.in.h
@@ -523,11 +523,18 @@ _GL_CXXALIAS_SYS (tzalloc, timezone_t, (char const 
*__name));
 #  endif
 
 /* tzfree (tz)
-   Frees a time zone object.
+   Free a time zone object, preserving errno.
    The argument must have been returned by tzalloc().  */
 #  if !@HAVE_TZALLOC@
 _GL_FUNCDECL_SYS (tzfree, void, (timezone_t __tz), );
 _GL_CXXALIAS_SYS (tzfree, void, (timezone_t __tz));
+#  else
+#   if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#    undef tzfree
+#    define tzfree rpl_tzfree
+#   endif
+_GL_FUNCDECL_RPL (tzfree, void, (timezone_t __tz), );
+_GL_CXXALIAS_RPL (tzfree, void, (timezone_t __tz));
 #  endif
 
 /* localtime_rz (tz, &t, &result)
diff --git a/lib/time_rz.c b/lib/time_rz.c
index 3a4336636f..8a8eb44c35 100644
--- a/lib/time_rz.c
+++ b/lib/time_rz.c
@@ -27,7 +27,10 @@
 /* Specification.  */
 #include <time.h>
 
-#if NEED_TIMEZONE_NULL_SUPPORT          /* Android API level >= 35 */
+#include <errno.h>
+
+#if HAVE_TZALLOC
+# if NEED_TIMEZONE_NULL_SUPPORT          /* Android API level >= 35 */
 
 struct tm *
 localtime_rz (timezone_t tz, time_t const *t, struct tm *tm)
@@ -48,10 +51,19 @@ mktime_z (timezone_t tz, struct tm *tm)
   else
     return mktime_z (tz, tm);
 }
+# endif
+
+void
+tzfree (timezone_t tz)
+# undef tzfree
+{
+  int err = errno;
+  tzfree (tz);
+  errno = err;
+}
 
 #else
 
-# include <errno.h>
 # include <stddef.h>
 # include <stdlib.h>
 # include <string.h>
@@ -212,9 +224,7 @@ set_tz (timezone_t tz)
         return old_tz;
       if (! change_env (tz))
         {
-          int saved_errno = errno;
           tzfree (old_tz);
-          errno = saved_errno;
           return NULL;
         }
       return old_tz;
diff --git a/m4/time_rz.m4 b/m4/time_rz.m4
index b85e6d0cbb..885463a03b 100644
--- a/m4/time_rz.m4
+++ b/m4/time_rz.m4
@@ -1,5 +1,5 @@
 # time_rz.m4
-# serial 3
+# serial 4
 dnl Copyright (C) 2015-2025 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -58,7 +58,8 @@ AC_DEFUN([gl_TIME_RZ],
   if test $ac_cv_func_tzalloc = yes; then
     HAVE_TZALLOC=1
   fi
-  dnl Assume that tzalloc, localtime_rz, mktime_z are all defined together.
+  dnl Assume that tzalloc, tzfree, localtime_rz, mktime_z
+  dnl are all defined together.
   case "$gl_cv_onwards_func_tzalloc" in
     yes)
       case "$host_os" in
diff --git a/modules/time_rz b/modules/time_rz
index 1981b81920..2479f04d17 100644
--- a/modules/time_rz
+++ b/modules/time_rz
@@ -9,6 +9,7 @@ m4/time_rz.m4
 Depends-on:
 c99
 extensions
+free-posix
 time-h
 flexmember     [test $HAVE_TZALLOC = 0 || test $REPLACE_LOCALTIME_RZ = 1 || 
test $REPLACE_MKTIME_Z = 1]
 idx            [test $HAVE_TZALLOC = 0 || test $REPLACE_LOCALTIME_RZ = 1 || 
test $REPLACE_MKTIME_Z = 1]
@@ -22,14 +23,10 @@ unsetenv       [test $HAVE_TZALLOC = 0 || test 
$REPLACE_LOCALTIME_RZ = 1 || test
 
 configure.ac:
 gl_TIME_RZ
-gl_CONDITIONAL([GL_COND_OBJ_TIME_RZ],
-               [test $HAVE_TZALLOC = 0 || test $REPLACE_LOCALTIME_RZ = 1 || 
test $REPLACE_MKTIME_Z = 1])
 gl_TIME_MODULE_INDICATOR([time_rz])
 
 Makefile.am:
-if GL_COND_OBJ_TIME_RZ
 lib_SOURCES += time_rz.c
-endif
 
 Include:
 <time.h>
-- 
2.51.0


Reply via email to