* Makefile, NEWS, newtzset.3: Mention this.
* localtime.c (FREE_PRESERVES_ERRNO):
Default to 1 if 'free' is known to preserve errno, 0 otherwise.
(tzfree): Preserve errno if 'free' does not.
---
 Makefile    |  2 ++
 NEWS        |  2 ++
 localtime.c | 15 +++++++++++++++
 newtzset.3  |  4 ++++
 4 files changed, 23 insertions(+)

diff --git a/Makefile b/Makefile
index 0fe8a9f8..0d33fa17 100644
--- a/Makefile
+++ b/Makefile
@@ -239,6 +239,8 @@ LDLIBS=
 #  -DEPOCH_OFFSET=N if the 'time' function returns a value N greater
 #      than what POSIX specifies, assuming local time is UT.
 #      For example, N is 252460800 on AmigaOS.
+#  -DFREE_PRESERVES_ERRNO=[01] if the 'free' function munges or preserves errno
+#      (default is guessed)
 #  -DHAVE_DECL_ASCTIME_R=0 if <time.h> does not declare asctime_r
 #      on POSIX platforms predating POSIX.1-2024
 #  -DHAVE_DECL_ENVIRON if <unistd.h> declares 'environ'
diff --git a/NEWS b/NEWS
index 1ed9b2eb..a9b2d321 100644
--- a/NEWS
+++ b/NEWS
@@ -93,6 +93,8 @@ Unreleased, experimental changes
     option is incompatible with POSIX.1-2024 and earlier.  It also
     costs CPU time and memory.
 
+    tzfree now preserves errno, consistently with POSIX.1-2024 'free'.
+
     tzcode now uses mempcpy if available, guessing its availability.
     Compile with -DHAVE_MEMPCPY=1 or 0 to override the guess.
 
diff --git a/localtime.c b/localtime.c
index b85941f2..46acf3bd 100644
--- a/localtime.c
+++ b/localtime.c
@@ -2061,10 +2061,25 @@ tzalloc(char const *name)
   return sp;
 }
 
+#ifndef FREE_PRESERVES_ERRNO
+# if ((defined _POSIX_VERSION && 202405 <= _POSIX_VERSION) \
+      || (defined __GLIBC__ && 2 < __GLIBC__ + (33 <= __GLIBC_MINOR__)) \
+      || defined __OpenBSD__ || defined __sun)
+#  define FREE_PRESERVES_ERRNO 1
+# else
+#  define FREE_PRESERVES_ERRNO 0
+# endif
+#endif
+
 void
 tzfree(timezone_t sp)
 {
+  int err;
+  if (!FREE_PRESERVES_ERRNO)
+    err = errno;
   free(sp);
+  if (!FREE_PRESERVES_ERRNO)
+    errno = err;
 }
 
 /*
diff --git a/newtzset.3 b/newtzset.3
index 3801ab1b..028cfd25 100644
--- a/newtzset.3
+++ b/newtzset.3
@@ -379,6 +379,10 @@ If successful, the
 function returns a nonnull pointer to the newly allocated object.
 Otherwise, it returns a null pointer and sets
 .IR errno .
+The
+.B tzfree
+function does not modify
+.IR errno .
 .SH ERRORS
 .TP
 .B EOVERFLOW
-- 
2.51.0

Reply via email to