]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
libc: Make sure C23 versions of strtol(), sscanf() are not used 42166/head
authorDaan De Meyer <daan@amutable.com>
Thu, 14 May 2026 19:20:02 +0000 (19:20 +0000)
committerDaan De Meyer <daan@amutable.com>
Mon, 18 May 2026 21:17:38 +0000 (21:17 +0000)
When _GNU_SOURCE is defined, glibc will always use c23 versions
of strtol(), sscanf() and friends if available (introduced after
glibc 2.34). Which means that any binaries built with headers
from newer glibc won't load on glibc < 2.38. To work around this,
redefine the appropriate constants to zero make sure the c99
versions are used instead.

meson.build
src/include/glibc/stdio.h [new file with mode: 0644]
src/include/glibc/stdlib.h [new file with mode: 0644]

index 8d5ee4f5792d7a26e0dc4752ac59d24fe78f0797..56b841ed359b5c68087a6a391e62d8d2cc344065 100644 (file)
@@ -1691,14 +1691,13 @@ system_includes = [
         ),
 ]
 
-if get_option('libc') == 'musl'
-        system_include_args = [
-                '-isystem', meson.project_build_root()  / 'src/include/musl',
-                '-isystem', meson.project_source_root() / 'src/include/musl',
-        ] + system_include_args
+libc_include_dir = 'src/include' / get_option('libc')
+system_include_args = [
+        '-isystem', meson.project_build_root()  / libc_include_dir,
+        '-isystem', meson.project_source_root() / libc_include_dir,
+] + system_include_args
 
-        system_includes += include_directories('src/include/musl', is_system : true)
-endif
+system_includes += include_directories(libc_include_dir, is_system : true)
 
 basic_includes = [
         include_directories(
diff --git a/src/include/glibc/stdio.h b/src/include/glibc/stdio.h
new file mode 100644 (file)
index 0000000..7e45cb3
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+/* Force glibc's stdio.h to route sscanf/fscanf to the old __isoc99_* siblings (GLIBC_2.7) rather
+ * than the newer __isoc23_* ones (GLIBC_2.38). The only behavioural difference is "0b" prefix
+ * support in %i conversions, which we don't use. We include features.h first so the macro is set
+ * to its normal value, then override it before stdio.h's body evaluates __GLIBC_USE(C23_STRTOL).
+ *
+ * The macro was named __GLIBC_USE_C2X_STRTOL on glibc 2.38–2.39 and renamed to the C23 spelling
+ * in glibc 2.40; clear both so this override works across that range. */
+
+#include <features.h>
+#undef __GLIBC_USE_C2X_STRTOL
+#define __GLIBC_USE_C2X_STRTOL 0
+#undef __GLIBC_USE_C23_STRTOL
+#define __GLIBC_USE_C23_STRTOL 0
+
+#include_next <stdio.h>      /* IWYU pragma: export */
diff --git a/src/include/glibc/stdlib.h b/src/include/glibc/stdlib.h
new file mode 100644 (file)
index 0000000..a3ad2a3
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+/* Force glibc's stdlib.h to leave strtol/strtoul/strtoll/strtoull as their original GLIBC_2.2.5
+ * symbols rather than redirect to __isoc23_* (GLIBC_2.38). The only behavioural difference is
+ * "0b" prefix support in base 0/2 parsing, which we don't use.
+ *
+ * The macro was named __GLIBC_USE_C2X_STRTOL on glibc 2.38–2.39 and renamed to the C23 spelling
+ * in glibc 2.40; clear both so this override works across that range. */
+
+#include <features.h>
+#undef __GLIBC_USE_C2X_STRTOL
+#define __GLIBC_USE_C2X_STRTOL 0
+#undef __GLIBC_USE_C23_STRTOL
+#define __GLIBC_USE_C23_STRTOL 0
+
+#include_next <stdlib.h>     /* IWYU pragma: export */