Bruno Haible [Tue, 28 Jul 2026 20:37:55 +0000 (22:37 +0200)]
tests: Avoid some more runtime errors with Fil-C.
* tests/test-c32ispunct.c (main): Skip a test case that fails on Fil-C.
* tests/test-free.c (main): Avoid converting from a pointer to uintptr_t
and back.
* tests/test-explicit_bzero.c (test_heap): Skip this test on Fil-C.
* tests/test-memset_explicit.c (test_heap): Likewise.
* tests/test-sigsegv-catch-segv1.c: Skip the entire test on Fil-C, since
it relies on converting an uintptr_t value to a pointer.
* tests/test-sigsegv-catch-segv2.c: Likewise.
Paul Eggert [Mon, 27 Jul 2026 20:31:35 +0000 (13:31 -0700)]
malloc: port to current -m32 AddressSanitizer
Also, port better to non-glibc, and in documentation update the
list of platforms needing a fix. This includes 32-bit platforms
using AddressSanitizer, unfortunately.
* m4/malloc.m4 (gl_CHECK_MALLOC_PTRDIFF): Invoke gl_MUSL_LIBC.
musl is safe, as is FreeBSD 11+, NetBSD 8+, OpenBSD 5.6+, AIX,
Microsoft Windows. However, the AddressSanitizer is unsafe.
Bruno Haible [Sun, 26 Jul 2026 22:48:34 +0000 (00:48 +0200)]
Pacify -fsanitize=address in rawmemchr, strchrnul also with clang < 22.
* lib/memchr.c (__has_feature): New macro.
(__memchr): Test the feature 'address_sanitizer'.
* lib/memchr2.c (__has_feature): New macro.
(memchr2): Test the feature 'address_sanitizer'.
* lib/rawmemchr.c (__has_feature): New macro.
(rawmemchr): Test the feature 'address_sanitizer'.
* lib/strchrnul.c (__has_feature): New macro.
(strchrnul): Test the feature 'address_sanitizer'.
Paul Eggert [Sun, 26 Jul 2026 20:46:46 +0000 (13:46 -0700)]
Pacify -fsanitize=address in rawmemchr, strchrnul
Problem reported by Lasse Collin in:
https://lists.gnu.org/r/bug-gnulib/2026-07/msg00174.html
* lib/memchr.c (__memchr), lib/memchr2.c (memchr2):
* lib/rawmemchr.c (rawmemchr), lib/strchrnul.c (strchrnul):
Omit the longword optimization if __SANITIZE_ADDRESS__.
Paul Eggert [Sun, 26 Jul 2026 18:49:42 +0000 (11:49 -0700)]
Fix strict aliasing violations in memchr etc
Problem and fix reported by Lasse Collin in:
https://lists.gnu.org/r/bug-gnulib/2026-07/msg00172.html
* lib/memchr.c (__memchr), lib/memchr2.c (memchr2):
* lib/memrchr.c (__memrchr), lib/rawmemchr.c (rawmemchr):
* lib/strchrnul.c (strchrnul):
Add _GL_ATTRIBUTE_MAY_ALIAS to the longword typedef.
Paul Eggert [Sun, 26 Jul 2026 18:43:06 +0000 (11:43 -0700)]
snprintf, vsnprintf: update doc
* doc/gnulib-intro.texi (Supported Platforms):
Also mention z/OS, Fil-C. Not sure where they should be listed
but I gave it a guess.
* doc/posix-functions/snprintf.texi (snprintf):
* doc/posix-functions/vsnprintf.texi (vsnprintf):
Also mention Fil-C bug.
Bruno Haible [Sat, 25 Jul 2026 23:15:14 +0000 (01:15 +0200)]
szprintf: Port to Fil-C.
* lib/szprintf.c (szprintf): Ensure lenbuf is at most INT_MAX.
* lib/vszprintf.c (vszprintf): Likewise.
* lib/unistdio/u-vsprintf.h (VSPRINTF): Ensure lenbuf is at most
INT_MAX / sizeof (DCHAR_T).
Paul Eggert [Sat, 25 Jul 2026 16:05:21 +0000 (09:05 -0700)]
gettext-h: conform to C on Solaris
On Solaris, gettext.h was sometimes converting char const * to char *
without a cast, which violates a constraint of the C standard.
GCC 3.4.3 complained about this. Though the compile succeeded
it’s better to not violate constraints when it’s easy.
* lib/gettext.h (gettext, dgettext, dcgettext)
[__sun && __GNUC__ && !__clang__ && !__cplusplus && !ENABLE_NLS]:
Cast msgid to char * before returning.
Paul Eggert [Sat, 25 Jul 2026 14:52:01 +0000 (07:52 -0700)]
verify: port to Solaris 10 + gcc 3.4.3 + assert-h
I ran into this problem when building GNU m4 (Savannah commit 7d5125b78d56dfa08b6bb4205428eb9962ad9244) on Solaris 10 sparc.
It has GCC 3.4.3 (csl-sol210-3_4-branch+sol_rpath),
which lacks _Static_assert. GNU m4 both uses assert-h and
includes <verify.h>, and without this patch the latter mistakenly
#undefs the _Static_assert that the former defined.
* lib/verify.h (_Static_assert) [_GL_STATIC_ASSERT]: Do not undef.
Paul Eggert [Sat, 18 Jul 2026 03:59:32 +0000 (20:59 -0700)]
diffseq: gcc bug 80922 should be fixed now
* lib/diffseq.h: Stop ignoring -Wmaybe-uninitialized and
-Wanalyzer-use-of-uninitialized-value in GCC 17 and later,
as the bug I reported to GCC seems to have been fixed.
Paul Eggert [Fri, 17 Jul 2026 20:47:19 +0000 (13:47 -0700)]
getopt: port to NetBSD git head gcc -Wuseless cast
Problem reported by Thomas Klausner in:
https://lists.gnu.org/r/emacs-devel/2026-07/msg00169.html
* lib/getopt-pfx-ext.h (__getopt_argv_const_is_empty): New macro,
defined to 1 when we define __getopt_argv_const to empty.
* lib/getopt1.c (ARGV_CAST): New macro.
(getopt_long, getopt_long_only): Use it.
Paul Eggert [Fri, 17 Jul 2026 17:50:24 +0000 (10:50 -0700)]
gendocs: output human-readable file sizes
* build-aux/gendocs.sh (calcsize): Output human-readable file
size, rather than always size in KiB mislabled as "K bytes".
But fall back on a plain byte count if GNU du is not in use.
(time-stamp-time-zone): Now "UTC0" so scriptversion does not decrease.
* doc/gendocs_template, doc/gendocs_template_min:
Don’t assume sizes are in KiB (the old values were mislabeled anyway).
Be more consistent about file type labels.
physmem: allow physmem_claimable to return more than 4 GiB on NetBSD.
Problem reported by Bruno Haible in:
<https://lists.gnu.org/r/bug-gnulib/2026-07/msg00046.html>.
* m4/physmem.m4 (gl_PHYSMEM): Check for the presence of
uvm/uvm_extern.h.
* lib/physmem.c [HAVE_UVM_UVM_EXTERN_H]: Include uvm/uvm_extern.h.
(physmem_claimable) [HAVE_SYSCTL && VM_UVMEXP2]: Calculate the free
memory using a NetBSD-specific sysctl.
physmem: allow physmem_claimable to return more than 8 GiB on FreeBSD.
Problem reported by Bruno Haible in:
<https://lists.gnu.org/r/bug-gnulib/2026-07/msg00046.html>.
* m4/physmem.m4 (gl_PHYSMEM): Check for the sysctlbyname function.
* lib/physmem.c (physmem_claimable) [HAVE_SYSCTLBYNAME && __FreeBSD__]:
Calculate of free memory from some FreeBSD-specific sysctl strings.
Bruno Haible [Tue, 14 Jul 2026 17:28:10 +0000 (19:28 +0200)]
vasnprintf-extra-tests: Refactor.
* tests/test-vasnprintf-big1.c: New file, based on
tests/test-vasnprintf-big.c.
* tests/test-vasnprintf-big2.c: New file, based on
tests/test-vasnprintf-big.c.
* tests/test-vasnprintf-big.c: Remove file.
* modules/vasnprintf-extra-tests: Update to build two separate programs.
Bruno Haible [Mon, 13 Jul 2026 21:06:33 +0000 (23:06 +0200)]
vaszprintf-extra-tests: New module.
* tests/test-vaszprintf-big.c: New file, extracted from
tests/test-vaszprintf-posix.c.
* tests/test-vaszprintf-posix.c (test_function): Revert last change.
* modules/vaszprintf-extra-tests: New file.
* modules/vaszprintf-tests: New file.
Paul Eggert [Tue, 7 Jul 2026 03:35:24 +0000 (20:35 -0700)]
vasnprintf: fix ("%*d", INT_MAX, n)
I ran into this problem when doing stress testing with GNU m4.
The problem is that ("%*d", INT_MAX, n) fails because the code
refuses to create a buffer of size INT_MAX + 1u,
due to problems when dealing with older nonconforming snprintf.
The simplest fix was to use snprintf only if it handles
sizes like INT_MAX + 1u, and to fall back on sprintf otherwise.
Nowadays I think snprintf should work on most practical targets.
Assuming this patch works out, perhaps we could simplify
lib/vasnprintf.c to ease further maintenance,
as nowadays I hope we can assume both HAVE_SNPRINTF_RETVAL_C99 and
HAVE_SNPRINTF_TRUNCATION_C99 on platforms where USE_SNPRINTF.
* lib/vasnprintf.c: Include minmax.h.
(USE_SNPRINTF): Define to 1 only if glibc 2+, Android, musl,
the BSDs, macOS, or Microsoft UCRT.
(VASNPRINTF) [USE_SNPRINTF]:
Allow maxlen to be 1 greater than INT_MAX on 64-bit platforms.
Document the limit’s derivation by using named locals.
Do not attempt to work around bugs in pre-C99 implementations,
as USE_SNPRINTF is pickier now.
* m4/vasnprintf.m4 (gl_PREREQ_VASNWPRINTF):
Move gl_MUSL_LIBC call from here ...
(gl_PREREQ_VASNXPRINTF): ... to here.
* modules/c-vasnprintf, modules/unistdio/u16-u16-vasnprintf:
* modules/unistdio/u16-vasnprintf:
* modules/unistdio/u32-u32-vasnprintf:
* modules/unistdio/u32-vasnprintf:
* modules/unistdio/u8-u8-vasnprintf:
* modules/unistdio/u8-vasnprintf, modules/unistdio/ulc-vasnprintf:
* modules/vasnprintf, modules/vasnwprintf:
(Files): Add m4/musl.m4 if it isn’t there already.
(Depends-on): Add minmax.
* tests/test-vasnprintf-posix.c:
* tests/test-vasprintf-posix.c:
* tests/test-vaszprintf-posix.c:
Include <limits.h> and <errno.h> if needed.
(test_function): Test for the bug, if RUN_EXPENSIVE_TESTS=yes
in the environment; this the coreutils tradition and I
didn’t see any Gnulib tradition so I just used it.
Paul Eggert [Fri, 26 Jun 2026 18:20:50 +0000 (11:20 -0700)]
bitset: possibly widen unsigned indexes
* lib/bitset/vector.c (vbitset_empty_p, vbitset_not)
(vbitset_disjoint_p, vbitset_and, vbitset_and_or)
(vbitset_and_or_cmp, vbitset_andn_or, vbitset_andn_or_cmp)
(vbitset_or_and, vbitset_or_and_cmp):
In a for-loop, use an index type related to the upper bound’s type
rather than trusting ‘unsigned’ to be wide enough.
Paul Eggert [Fri, 26 Jun 2026 17:29:05 +0000 (10:29 -0700)]
bitrotate: prefer C2y to bitrotate or by-hand
Deprecate the bitrotate module; it is superseded by C2y’s
stdc_rotate_left and stdc_rotate_right. In several places, prefer
the C2y functions to doing things by hand.
* lib/arctwo.c (arctwo_encrypt, arctwo_decyrpt):
* lib/hash.c (raw_hasher):
* lib/hashcode-mem.c (hash_pjw_bare):
* lib/hashcode-string1.c (hash_string):
* lib/hashcode-string2.c (hash_pjw):
* lib/hashkey-string.c (hashkey_string_hash):
* lib/mem-hash-map.c (compute_hashval):
* lib/struniq.h (hash):
* tests/test-array_map.c (string_hash):
* tests/test-avltreehash_list.c (string_hash):
* tests/test-hash_map.c (string_hash):
* tests/test-linkedhash_list.c (string_hash):
* tests/test-linkedhash_map.c (string_hash):
* tests/test-rbtreehash_list.c (string_hash):
Use stdbit.h functions, instead of bitrotate.h functions or doing
things by hand. Include stdbit.h to get them. Don’t include
bitrotate.h, if it was being included.
* lib/getlocalename_l-unsafe.c, lib/getlocalename_l.c:
* lib/localename.c:
Include stdbit.h, since struniq.h now needs this.
* lib/hashcode-mem.c, lib/hashcode-string2.c, lib/hashkey-string.c:
* lib/struniq.h, tests/test-array_map.c, tests/test-avltreehash_list.c:
* tests/test-hash_map.c, tests/test-linkedhash_list.c:
* tests/test-linkedhash_map.c, tests/test-rbtreehash_list.c:
(SIZE_BITS): Remove; no longer needed.
* modules/array-map-tests, modules/avltreehash-list-tests:
* modules/crypto/arctwo, modules/getlocalename_l-simple:
* modules/getlocalename_l-unsafe, modules/hash:
* modules/hash-map-tests, modules/hashcode-mem:
* modules/hashcode-string1, modules/hashcode-string2:
* modules/hashkey-string, modules/linkedhash-list-tests:
* modules/linkedhash-map-tests, modules/localename:
* modules/mem-hash-map, modules/rbtree-list-tests:
Depend on stdc_rotate_left.
Don’t depend on bitrotate, if we were depending on it.
* modules/bitrotate: Deprecate.
* modules/crypto/arctwo: Depend on stdc_rotate_right.
Paul Eggert [Thu, 25 Jun 2026 15:27:36 +0000 (08:27 -0700)]
fstatat: port null file support to Alpine 3.24
Problem reported by Bruno Haible in:
https://lists.gnu.org/r/bug-gnulib/2026-06/msg00093.html
* m4/fstatat.m4 (gl_FUNC_FSTATAT): When checking for
support for a null pointer file, check nonnegative directory
file descriptors as well as AT_FDCWD.
Paul Eggert [Sat, 20 Jun 2026 17:45:10 +0000 (10:45 -0700)]
gethrxtime: don’t use nanouptime, microuptime
* lib/gethrxtime.c (gethrxtime): On platforms with
CLOCK_MONOTONIC, try it first. If it fails, just fall back on
CLOCK_REALTIME as that’s what current_timespec would do anyway.
On platforms lacking CLOCK_MONOTONIC, just use current_timespec.
* m4/gethrxtime.m4 (gl_GETHRXTIME): Don’t check for microuptime or
nanouptime. They aren’t exposed to user space by BSD kernels now,
and it’s not clear that they ever were.
Paul Eggert [Fri, 19 Jun 2026 17:07:47 +0000 (10:07 -0700)]
fstatat: don’t mess with CFLAGS
* m4/fstatat.m4 (gl_FUNC_FSTATAT): Remove stray code left
over from an aborted attempt to mess with CFLAGS.
Problem reported by Bruno Haible in:
https://lists.gnu.org/r/bug-gnulib/2026-06/msg00084.html
Paul Eggert [Fri, 19 Jun 2026 16:27:30 +0000 (09:27 -0700)]
openat2-tests: port to NFS
* tests/test-openat2.c (do_test_basic): Close fd before
removing its file. This fixes a file descriptor leak,
and ports the test to NFS, where removing an unclosed
file leaves behind a .nfs* file that prevents the
parent directory from being removed.
Paul Eggert [Fri, 19 Jun 2026 16:17:04 +0000 (09:17 -0700)]
openat2: fix typo for circa-2012 Linux
* lib/openat2.c (dirstat) [FSTAT_O_PATH_BUG]: Fix typo (a missing
arg) in workaround for this bug in Linux kernel 2.6.39 (2011)
through 3.5.7 (2012). Evidently nobody compiles on these old
platforms, but we might as well fix the code if we’re going to
have it at all.
Paul Eggert [Thu, 18 Jun 2026 20:33:58 +0000 (13:33 -0700)]
fstatat: support NULL if AT_EMPTY_PATH
On platforms that define AT_EMPTY_PATH, allow a null pointer to be
passed as a file name. This is GNU behavior as of glibc 2.41 +
Linux kernel 6.11, and can be supported on older kernels, older
glibcs, and on recent FreeBSD and z/OS.
* lib/fstatat.c (rpl_fstatat): Support AT_EMPTY_PATH,
if it exists, on null pointers.
* m4/fstatat.m4 (gl_FUNC_FSTATAT): Replace fstatat if
AT_EMPTY_PATH is defined but does not work on null pointers.
Also, define HAVE_WORKING_FSTATAT_ZERO_FLAG, if it is discovered,
regardless of whether replacing fstatat. This refactoring makes
config.h a bit less confusing.
* tests/test-fstatat.c (main): Test AT_EMPTY_PATH if defined.
Paul Eggert [Thu, 18 Jun 2026 16:29:15 +0000 (09:29 -0700)]
fchmodat: fix AT_FDCWD + AT_EMPTY_PATH
* lib/fchmodat.c (fchmodat): When following symlinks and with
AT_FDCWD and an empty filename, don’t use fchmod as it will fail.
Instead, fall back on the usual orig_fchmodat call, as this does
the right thing if AT_EMPTY_PATH support is present there.
Using chmod (".", ...) wouldn’t be quite right here, as it would
go awry if the working directory is not searchable.
Problem reported by Bruno Haible in:
https://lists.gnu.org/r/bug-gnulib/2026-06/msg00068.html
Paul Eggert [Wed, 17 Jun 2026 07:19:35 +0000 (00:19 -0700)]
openat2: fix bug with trailing "/./"
Problem reported by Kinan Al-Falakh in:
https://lists.gnu.org/r/bug-gnulib/2026-06/msg00070.html
* lib/openat2.c (do_openat2): When opening a dotlike component at
file name end, also set the G and H indexes appropriately for ".".
This matters if the file name ends in something like "/./" so the
last component "." is not at file name end.
* tests/test-openat2.c (do_test_resolve): Test for the bug.
Paul Eggert [Wed, 17 Jun 2026 06:59:47 +0000 (23:59 -0700)]
openat2: set HAVE_OPENAT2=0 if openat2 is missing
* m4/openat2.m4 (gl_FUNC_OPENAT2): The recent ‘fcntl-h: glibc now
has openat2’ patch changed HAVE_OPENAT2’s default to 1. Adjust to
this here by setting it to 0 when openat2 is not found, rather than
setting it to 1 when it is found.
Paul Eggert [Tue, 16 Jun 2026 16:46:20 +0000 (09:46 -0700)]
fchownat: don’t mishandle AT_EMPTY_PATH
This has the same motivation as the recent fchmodat change.
* lib/fchownat.c (AT_EMPTY_PATH): Default to 0.
(FCHOWNAT_EMPTY_FILENAME_BUG): Remove; no longer needed.
(rpl_fchownat): Do not mishandle AT_EMPTY_PATH if specified
and if the underlying library+kernel supports it.
* m4/fchownat.m4 (gl_FUNC_FCHOWNAT):
Don’t define FCHOWNAT_EMPTY_FILENAME_BUG, as it is no longer needed.
Paul Eggert [Tue, 16 Jun 2026 16:46:03 +0000 (09:46 -0700)]
fchmodat: don’t mishandle AT_EMPTY_PATH
This does not add support for AT_EMPTY_PATH on platforms lacking it.
It merely fixes bugs in handling AT_EMPTY_PATH on platforms
that already have AT_EMPTY_PATH. This is complicated by
the fact that glibc may define AT_EMPTY_PATH even though the
underlying kernel lacks support for it, and by the fact that
in recent kernels, AT_EMPTY_PATH allows the file name to be
a null pointer.
* lib/fchmodat.c (AT_EMPTY_PATH): Default to 0.
(rpl_fchmodat): Do not mishandle AT_EMPTY_PATH if specified
and if the underlying library+kernel supports it.
Paul Eggert [Tue, 16 Jun 2026 16:45:39 +0000 (09:45 -0700)]
fstatat etc.: fix wrong machine code for calls
Without this fix, compilers can generate incorrect machine code
for functions that call to fstatat-like functions, as the
compilers incorrectly assume that the calls’ arguments cannot be
null pointers. This assumption became false with the release of
Linux kernel 6.11 (2024).
* lib/sys_stat.in.h (fchmodat, fstatat, utimensat):
* lib/unistd.in.h (faccessat, fchownat): Do not mark file args
with _GL_ARG_NONNULL, as the args are allowed to be null pointers
in Linux kernel 6.11+, possibly with glibc 2.41+ involved.
Paul Eggert [Tue, 16 Jun 2026 16:44:54 +0000 (09:44 -0700)]
faccessat: support "" and NULL file
* lib/faccessat.c (LSTAT_FOLLOWS_SLASHED_SYMLINK): Default to 0.
(rpl_faccessat): Don’t mishandle empty string, or null pointer for
that matter. Also, do not call fstatat if
LSTAT_FOLLOWS_SLASHED_SYMLINK, as there is no need in that case.