* lib/regex_internal.c (re_node_set_insert): Remove the DEBUG_ASSERT
and instead return early for an attempt to insert an ELEM that is
already present in the set. Relax the function's comment that says
there should be no duplicate. This function is called from many
places and has been working fine. With its nontrivial backrefs,
the sample regexp apparently elicits enough backtracking retries
and state-set merges to trigger this duplicate insertion attempt.
Reported by Bruno Haible in
https://lists.gnu.org/r/bug-gnulib/2026-04/msg00138.html
* lib/fts.in.h (FTS_NOSTAT): Use a FIFO, not a directory,
in the commentary’s example. This is a better example
because directories never have FTS_NSOK.
Reported by Pádraig Brady.
* tests/test-pthread_sigmask2.c (main): Reestablish the signal handler
after SIGINT arrived.
* tests/test-sigdelay2.c (main): Likewise.
* tests/test-sigdelay1.c: New file, based on
tests/test-pthread_sigmask1.c.
* tests/test-sigdelay2.c: New file, based on
tests/test-pthread_sigmask2.c.
* modules/sigdelay-tests: New file.
* tests/test-pthread_sigmask2.c (killer_thread1): Renamed from
killer_thread.
(killer_thread2): New variable.
(killer_thread1_func): Renamed from killer_thread_func.
(killer_thread2_func): New function.
(main): Add a second test with killer_thread2.
* lib/stdbit.in.h: With the Intel icpx C++ compiler, include <stddef.h>
and <stdint.h>, and define the __STDC_ENDIAN_* macros.
* doc/posix-headers/stdbit.texi: Document the Intel icpx bug.
* lib/regexec.c (re_search_internal): Use only one copy
of the 5-line reg-initialization code, removing that else block,
at the tiny cost of moving a small test into the loop.
With a backref pattern like ^(.?)(.?).?\2\1 (no $), the engine
could miss valid short matches. For example, "ab" should match
via all-empty groups, yet regexec returned no-match because
set_regs failed at the longest structural match (match_last=2)
and never retried at a shorter match_last.
* lib/regexec.c (re_search_internal): When set_regs fails for a
backref pattern, retry prune_impossible_nodes and set_regs at
progressively shorter match lengths. Save a copy of state_log
before pruning so shorter retries can re-sift from the original
states.
* m4/regex.m4: Also reject system regex with this bug.
* tests/test-regex.c (main): Add a test for this bug.
Reported by Ed Morton in https://bugs.gnu.org/68725
Co-authored-by: Claude <noreply@anthropic.com>
Use of sed or grep with both backreferences and an end-of-line
anchor could get false matches. For example, this grep command
would falsely declare "ab" to be a palindrome:
grep -E '^(.?)(.?).?\2\1$' <<< ab
In prune_impossible_nodes, falling back to a shorter match
skipped the halt-state context check, so $ was not verified.
* lib/regexec.c (prune_impossible_nodes): Also require
check_halt_state_context to succeed in the loop that searches
for an earlier halt state.
* m4/regex.m4: Bump serial to 82. Reject any system regex
implementation with this bug.
* tests/test-regex.c (main): Add a test for this bug.
Reported by Ed Morton in https://bugs.gnu.org/68725
* lib/tempname.c (random_bits) [CLOCK_REALTIME]: Do not call
‘clock’, as an optimization. There is no need to call ‘clock’, as
it likely gives us less info than clock_gettime, and if
clock_gettime fails then ‘clock’ will likely fail too.
This patch is a simplified version of the patch made in glibc commit
5f62cf88c4530c11904482775b7582bd7f6d80d2 dated 2024-09-25,
and Gnulib lib/tempname.c should now be suitable as-is for
replacing Glibc sysdeps/posix/tempname.c.
In documentation and comments, be more like POSIX in terminology
involving multithreading. Explain the distinction between
multithreaded process vs multithreaded program. Change “program”
to “process” when the latter wording is more accurate or informative.
Simplify the wording for the constraints on processes that use
unlocked I/O. Change “multithread-safe” to “thread-safe”.
Change “thread-safety” to “thread safety”.
However, do not change “multithreaded” to “multi-threaded” even
though there are some uses of both spellinga, as there are a whole
bunch of uses of “multithreaded”, also in identifier names;
perhaps Gnulib should even standardize on “multithreaded”
(not “multi-threaded”), contra POSIX.
* lib/sigprocmask.c (glwthread_spin_lock, glwthread_spin_unlock): Define
to empty if GNULIB_SIGPROCMASK_SINGLE_THREAD is defined.
(overrides_mt_lock, overrides_handler_lock): Don't define if
GNULIB_SIGPROCMASK_SINGLE_THREAD is defined.
* doc/multithread.texi (Multithreading Optimizations): Document
GNULIB_SIGPROCMASK_SINGLE_THREAD instead of
GNULIB_PTHREAD_SIGMASK_SINGLE_THREAD.
* lib/sigprocmask.c (overrides_handler_lock): Renamed from
overrides_lock.
(overrides_mt_lock): New variable.
(pthread_sigmask): Lock both locks.
(rpl_signal): Lock overrides_mt_lock, not overrides_lock.
* lib/signal.in.h (WIN_PTHREADS_SIGNAL_H): New macro.
* lib/sigprocmask.c: Include windows-spin.h.
(thread_local): New macro.
(blocked_set, pending_array): Mark as thread-local.
(blocked_handler): Remove function.
(struct override): New type.
(overrides, overrides_lock): New variables.
(override_handler): New function.
(pthread_sigmask): New function, borrowing from the previous sigprocmask
definition.
(sigprocmask): Now a wrapper around pthread_sigmask.
(rpl_signal): Use the overrides_lock to make it multithread-safe.
(_gl_raise_SIGPIPE): Add comments.
* modules/sigprocmask (Depends-on): Add windows-spin.
* lib/pthread_sigmask.c: Revert last change. On native Windows, don't
define pthread_sigmask here.
* modules/pthread_sigmask (Depends-on): Remove lock.
* NEWS: Remove the last entry.
* lib/term-style-control.c (block_relevant_signals)
(unblock_relevant_signals): Prefer pthread_sigmask to sigprocmask.
* modules/term-style-control (Depends-on):
Depend on pthread_sigmask, not on sigprocmask.
* lib/fatal-signal.c (block_fatal_signals)
(unblock_fatal_signals): Prefer pthread_sigmask to sigprocmask.
* modules/fatal-signal (Depends-on):
Depend on pthread_sigmask, not on sigprocmask.
* lib/sigaction.c (sigaction_handler, sigaction):
Use pthread_sigmask, not sigprocmask.
* modules/sigaction (Depends-on):
Depend on pthread_sigmask, not on sigprocmask.
Since sigprocmask should now be used only in single-threaded processes,
move the locking from lib/sigprocmask.c to lib/pthread_sigmask.c.
* lib/pthread_sigmask.c: If !HAVE_SIGPROCMASK &&
!GNULIB_PTHREAD_SIGMASK_SINGLE_THREAD, replace Gnulib sigprocmask
with a thread-safe subsitute sigprocmask_r.
Include glthread/lock.h to implement this.
* lib/sigprocmask.c (gl_lock_define_initialized, gl_lock_lock)
(gl_lock_unlock, sig_lock): Remove. All uses removed.
Do not include glthread/lock.h.
* m4/signalblocking.m4 (gl_SIGNALBLOCKING):
Define HAVE_SIGPROCMASK, for the benefit of pthread_sigmask.c.
* modules/pthread_sigmask (Depends-on): Add ‘lock’.
* modules/sigprocmask (Depends-on): Remove ‘lock’.
This is a performance win on GLIBC,
as tested on the coreutils multi-byte update to cut(1):
$ yes $(yes éééááé | head -n9 | paste -s -d,) |
head -n1M > mb.in
$ time LC_ALL=C.UTF-8 src/cut-before -c1 mb.in >/dev/null
real 0m1.582s
$ time LC_ALL=C.UTF-8 src/cut-after -c1 mb.in >/dev/null
real 0m0.592s
* lib/mcel.h: While GLIBC's mbrtoc32 is functional for mcel,
it is seen to be 2.6x slower than gnulib's implementation
due to GLIBC's per call locale handling.
Suggested by Paul Eggert.
* tests/test-asyncsafe-linked_list-strong.c (block_sigint): Use
pthread_sigmask instead of sigprocmask.
* tests/test-asyncsafe-linked_list-weak.c (block_sigint): Likewise.
Suggested by Paul Eggert.
* lib/asyncsafe-spin.c (asyncsafe_spin_lock, asyncsafe_spin_unlock): Use
pthread_sigmask instead of sigprocmask.
* modules/asyncsafe-spin (Depends-on): Add pthread_sigmask. Remove
sigprocmask.
(Link): New section.
* modules/asyncsafe-spin-tests (Makefile.am): Link test-asyncsafe-spin1
with $(PTHREAD_SIGMASK_LIB).
* modules/jit/cache-tests (Makefile.am): Link test-cache with
$(PTHREAD_SIGMASK_LIB).
Suggested by Paul Eggert.
* lib/spawn-pipe.c (execute): Use pthread_sigmask to get the set of
blocked signals.
* modules/spawn-pipe (Depends-on): Add pthread_sigmask.
Suggested by Paul Eggert.
* lib/execute.c (execute): Use pthread_sigmask to get the set of blocked
signals.
* modules/execute (Depends-on): Add pthread_sigmask.
* m4/pthread_sigmask.m4 (gl_FUNC_PTHREAD_SIGMASK): Define
PTHREAD_SIGMASK_LIB to empty, except on AIX. Define
PTHREAD_SIGMASK_NOT_IN_LIBC if a workaround is needed.
* lib/pthread_sigmask.c (pthread_sigmask): If
PTHREAD_SIGMASK_NOT_IN_LIBC, just use sigprocmask.
* doc/posix-functions/pthread_sigmask.texi: Mention the dropped link
requirement. Mention that the NetBSD 9 bug is fixed.
* doc/posix-functions/sigprocmask.texi: Update note relating to
pthread_sigmask.