Commit 2209f63 for zlib

commit 2209f63bda59360dd2fe765b71f89d84955ddd24
Author: Mark Adler <git@madler.net>
Date:   Sun Jan 18 10:18:46 2026 -0800

    Make z_once() local to avoid conditional external symbols.

diff --git a/crc32.c b/crc32.c
index 630049f..4cc573f 100644
--- a/crc32.c
+++ b/crc32.c
@@ -24,8 +24,11 @@
 #  include <stdio.h>
 #  ifndef DYNAMIC_CRC_TABLE
 #    define DYNAMIC_CRC_TABLE
-#  endif /* !DYNAMIC_CRC_TABLE */
-#endif /* MAKECRCH */
+#  endif
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+#  define Z_ONCE
+#endif

 #include "zutil.h"      /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */

diff --git a/inftrees.c b/inftrees.c
index c050f8b..6b6f8dc 100644
--- a/inftrees.c
+++ b/inftrees.c
@@ -3,6 +3,15 @@
  * For conditions of distribution and use, see copyright notice in zlib.h
  */

+#ifdef MAKEFIXED
+#  ifndef BUILDFIXED
+#    define BUILDFIXED
+#  endif
+#endif
+#ifdef BUILDFIXED
+#  define Z_ONCE
+#endif
+
 #include "zutil.h"
 #include "inftrees.h"
 #include "inflate.h"
diff --git a/zlib.map b/zlib.map
index d0b8a20..6c4c031 100644
--- a/zlib.map
+++ b/zlib.map
@@ -113,5 +113,4 @@ ZLIB_1.3.2 {
 	uncompress2_z;
   local:
     inflate_fixed;
-    z_once;
 } ZLIB_1.3.1.2;
\ No newline at end of file
diff --git a/zutil.c b/zutil.c
index 3a94e91..6e8a369 100644
--- a/zutil.c
+++ b/zutil.c
@@ -305,61 +305,3 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {
 #endif /* MY_ZCALLOC */

 #endif /* !Z_SOLO */
-
-#if defined(BUILDFIXED) || defined(DYNAMIC_CRC_TABLE)
-/*
-  Define a z_once() function depending on the availability of atomics.
- */
-
-/* Check for the availability of atomics. */
-#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \
-    !defined(__STDC_NO_ATOMICS__)
-
-#include <stdatomic.h>
-
-/*
-  Run the provided init() function exactly once, even if multiple threads
-  invoke once() at the same time. The state must be a once_t initialized with
-  Z_ONCE_INIT.
- */
-void z_once(z_once_t *state, void (*init)(void)) {
-    if (!atomic_load(&state->done)) {
-        if (atomic_flag_test_and_set(&state->begun))
-            while (!atomic_load(&state->done))
-                ;
-        else {
-            init();
-            atomic_store(&state->done, 1);
-        }
-    }
-}
-
-#else   /* no atomics */
-
-#warning zlib not thread-safe
-
-/* Test and set. Alas, not atomic, but tries to limit the period of
-   vulnerability. */
-local int test_and_set(int volatile *flag) {
-    int was;
-
-    was = *flag;
-    *flag = 1;
-    return was;
-}
-
-/* Run the provided init() function once. This is not thread-safe. */
-void z_once(z_once_t *state, void (*init)(void)) {
-    if (!state->done) {
-        if (test_and_set(&state->begun))
-            while (!state->done)
-                ;
-        else {
-            init();
-            state->done = 1;
-        }
-    }
-}
-
-#endif
-#endif
diff --git a/zutil.h b/zutil.h
index 94fa1af..acc1907 100644
--- a/zutil.h
+++ b/zutil.h
@@ -254,30 +254,74 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
 #define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
                     (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))

-#ifdef MAKEFIXED
-#  ifndef BUILDFIXED
-#    define BUILDFIXED
-#  endif
-#endif
-#if defined(BUILDFIXED) || defined(DYNAMIC_CRC_TABLE)
-/* Structure for z_once(), which must be initialized with Z_ONCE_INIT. */
-typedef struct z_once_s z_once_t;
-void ZLIB_INTERNAL z_once(z_once_t *state, void (*init)(void));
+#ifdef Z_ONCE
+/*
+  Create a local z_once() function depending on the availability of atomics.
+ */
+
+/* Check for the availability of atomics. */
 #if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \
     !defined(__STDC_NO_ATOMICS__)
+
 #include <stdatomic.h>
-struct z_once_s {
+typedef struct {
     atomic_flag begun;
     atomic_int done;
-};
+} z_once_t;
 #define Z_ONCE_INIT {ATOMIC_FLAG_INIT, 0}
-#else   /* no atomics! */
-struct z_once_s {
+
+/*
+  Run the provided init() function exactly once, even if multiple threads
+  invoke once() at the same time. The state must be a once_t initialized with
+  Z_ONCE_INIT.
+ */
+local void z_once(z_once_t *state, void (*init)(void)) {
+    if (!atomic_load(&state->done)) {
+        if (atomic_flag_test_and_set(&state->begun))
+            while (!atomic_load(&state->done))
+                ;
+        else {
+            init();
+            atomic_store(&state->done, 1);
+        }
+    }
+}
+
+#else   /* no atomics */
+
+#warning zlib not thread-safe
+
+typedef struct z_once_s {
     volatile int begun;
     volatile int done;
-};
+} z_once_t;
 #define Z_ONCE_INIT {0, 0}
-#endif
-#endif
+
+/* Test and set. Alas, not atomic, but tries to limit the period of
+   vulnerability. */
+local int test_and_set(int volatile *flag) {
+    int was;
+
+    was = *flag;
+    *flag = 1;
+    return was;
+}
+
+/* Run the provided init() function once. This is not thread-safe. */
+local void z_once(z_once_t *state, void (*init)(void)) {
+    if (!state->done) {
+        if (test_and_set(&state->begun))
+            while (!state->done)
+                ;
+        else {
+            init();
+            state->done = 1;
+        }
+    }
+}
+
+#endif /* ?atomics */
+
+#endif /* Z_ONCE */

 #endif /* ZUTIL_H */