summaryrefslogtreecommitdiff
path: root/tests/sigprocmask.c
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff.email>2026-03-10 13:24:07 +0100
committerJörg Frings-Fürst <debian@jff.email>2026-03-10 13:24:07 +0100
commitcfd1f17f1a85d95ea12bca8dae42add7dad1ad11 (patch)
tree8016486f8ee7157213f2d09ff2491bfa9c94638a /tests/sigprocmask.c
parent14e4d584d0121031ec40e6c35869745f1747ff29 (diff)
parent1403307d6e2fb4e7b5d97a35f40d1e95134561ab (diff)
Merge branch 'release/debian/1.4.2-1'HEADdebian/1.4.2-1master
Diffstat (limited to 'tests/sigprocmask.c')
-rw-r--r--tests/sigprocmask.c58
1 files changed, 33 insertions, 25 deletions
diff --git a/tests/sigprocmask.c b/tests/sigprocmask.c
index 3df69b51..2399f58e 100644
--- a/tests/sigprocmask.c
+++ b/tests/sigprocmask.c
@@ -1,5 +1,5 @@
/* POSIX compatible signal blocking.
- Copyright (C) 2006-2024 Free Software Foundation, Inc.
+ Copyright (C) 2006-2026 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2006.
This file is free software: you can redistribute it and/or modify
@@ -24,6 +24,8 @@
#include <stdint.h>
#include <stdlib.h>
+#include "glthread/lock.h"
+
#if HAVE_MSVC_INVALID_PARAMETER_HANDLER
# include "msvc-inval.h"
#endif
@@ -84,6 +86,10 @@ signal_nothrow (int sig, handler_t handler)
# define signal signal_nothrow
#endif
+/* This lock protects the variables defined in this file from concurrent
+ modification in multiple threads. */
+gl_lock_define_initialized(static, sig_lock)
+
/* Handling of gnulib defined signals. */
#if GNULIB_defined_SIGPIPE
@@ -182,7 +188,7 @@ sigfillset (sigset_t *set)
}
/* Set of currently blocked signals. */
-static volatile sigset_t blocked_set /* = 0 */;
+static sigset_t blocked_set /* = 0 */;
/* Set of currently blocked and pending signals. */
static volatile sig_atomic_t pending_array[NSIG] /* = { 0 } */;
@@ -205,11 +211,10 @@ int
sigpending (sigset_t *set)
{
sigset_t pending = 0;
- int sig;
-
- for (sig = 0; sig < NSIG; sig++)
+ for (int sig = 0; sig < NSIG; sig++)
if (pending_array[sig])
pending |= 1U << sig;
+
*set = pending;
return 0;
}
@@ -221,15 +226,14 @@ static volatile handler_t old_handlers[NSIG];
int
sigprocmask (int operation, const sigset_t *set, sigset_t *old_set)
{
+ gl_lock_lock (sig_lock);
+
if (old_set != NULL)
*old_set = blocked_set;
if (set != NULL)
{
sigset_t new_blocked_set;
- sigset_t to_unblock;
- sigset_t to_block;
-
switch (operation)
{
case SIG_BLOCK:
@@ -242,31 +246,28 @@ sigprocmask (int operation, const sigset_t *set, sigset_t *old_set)
new_blocked_set = blocked_set & ~*set;
break;
default:
+ gl_lock_unlock (sig_lock);
errno = EINVAL;
return -1;
}
- to_unblock = blocked_set & ~new_blocked_set;
- to_block = new_blocked_set & ~blocked_set;
- if (to_block != 0)
- {
- int sig;
+ sigset_t to_unblock = blocked_set & ~new_blocked_set;
+ sigset_t to_block = new_blocked_set & ~blocked_set;
- for (sig = 0; sig < NSIG; sig++)
- if ((to_block >> sig) & 1)
- {
- pending_array[sig] = 0;
- if ((old_handlers[sig] = signal (sig, blocked_handler)) != SIG_ERR)
- blocked_set |= 1U << sig;
- }
- }
+ if (to_block != 0)
+ for (int sig = 0; sig < NSIG; sig++)
+ if ((to_block >> sig) & 1)
+ {
+ pending_array[sig] = 0;
+ if ((old_handlers[sig] = signal (sig, blocked_handler)) != SIG_ERR)
+ blocked_set |= 1U << sig;
+ }
if (to_unblock != 0)
{
sig_atomic_t received[NSIG];
- int sig;
- for (sig = 0; sig < NSIG; sig++)
+ for (int sig = 0; sig < NSIG; sig++)
if ((to_unblock >> sig) & 1)
{
if (signal (sig, old_handlers[sig]) != blocked_handler)
@@ -281,11 +282,13 @@ sigprocmask (int operation, const sigset_t *set, sigset_t *old_set)
else
received[sig] = 0;
- for (sig = 0; sig < NSIG; sig++)
+ for (int sig = 0; sig < NSIG; sig++)
if (received[sig])
raise (sig);
}
}
+
+ gl_lock_unlock (sig_lock);
return 0;
}
@@ -334,11 +337,16 @@ rpl_signal (int sig, handler_t handler)
int
_gl_raise_SIGPIPE (void)
{
+ gl_lock_lock (sig_lock);
if (blocked_set & (1U << SIGPIPE))
- pending_array[SIGPIPE] = 1;
+ {
+ pending_array[SIGPIPE] = 1;
+ gl_lock_unlock (sig_lock);
+ }
else
{
handler_t handler = SIGPIPE_handler;
+ gl_lock_unlock (sig_lock);
if (handler == SIG_DFL)
exit (128 + SIGPIPE);
else if (handler != SIG_IGN)