1 /* Tests for pthread_attr_setsigmask_np, pthread_attr_getsigmask_np.
2 Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 /* This thread uses different masked status for SIGUSR1, SIGUSR2,
20 SIGHUP to determine if signal masks are applied to new threads as
27 #include <support/check.h>
28 #include <support/xsignal.h>
29 #include <support/xthread.h>
32 typedef bool signals
[_NSIG
];
35 masked_or_unmasked (bool masked
)
43 /* Report an error if ACTUAL_MASK does not match EXPECTED_MASK.
44 CONTEXT is used in error messages. */
46 check_sigmask (const char *context
, signals expected_mask
,
47 const sigset_t
*actual_mask
)
49 for (int sig
= 1; sig
< _NSIG
; ++sig
)
50 if (sigismember (actual_mask
, sig
) != expected_mask
[sig
])
52 support_record_failure ();
53 printf ("error: %s: signal %d should be %s, but is %s\n",
55 masked_or_unmasked (sigismember (actual_mask
, sig
)),
56 masked_or_unmasked (expected_mask
[sig
]));
60 /* Report an error if the current thread signal mask does not match
61 EXPECTED_MASK. CONTEXT is used in error messages. */
63 check_current_sigmask (const char *context
, signals expected_mask
)
66 xpthread_sigmask (SIG_SETMASK
, NULL
, &actual_mask
);
67 check_sigmask (context
, expected_mask
, &actual_mask
);
70 /* Thread start routine which checks the current thread signal mask
73 check_sigmask_thread_function (void *closure
)
75 check_current_sigmask ("on thread", closure
);
79 /* Same for C11 threads. */
81 check_sigmask_thread_function_c11 (void *closure
)
83 check_current_sigmask ("on C11 thread", closure
);
87 /* Launch a POSIX thread with ATTR (which can be NULL) and check that
88 it has the expected signal mask. */
90 check_posix_thread (pthread_attr_t
*attr
, signals expected_mask
)
92 xpthread_join (xpthread_create (attr
, check_sigmask_thread_function
,
96 /* Launch a C11 thread and check that it has the expected signal
99 check_c11_thread (signals expected_mask
)
102 TEST_VERIFY_EXIT (thrd_create (&thr
, check_sigmask_thread_function_c11
,
103 expected_mask
) == thrd_success
);
104 TEST_VERIFY_EXIT (thrd_join (thr
, NULL
) == thrd_success
);
110 check_current_sigmask ("initial mask", (signals
) { false, });
111 check_posix_thread (NULL
, (signals
) { false, });
112 check_c11_thread ((signals
) { false, });
116 sigaddset (&set
, SIGUSR1
);
117 xpthread_sigmask (SIG_SETMASK
, &set
, NULL
);
118 check_current_sigmask ("SIGUSR1 masked", (signals
) { [SIGUSR1
] = true, });
119 /* The signal mask is inherited by the new thread. */
120 check_posix_thread (NULL
, (signals
) { [SIGUSR1
] = true, });
121 check_c11_thread ((signals
) { [SIGUSR1
] = true, });
124 xpthread_attr_init (&attr
);
125 TEST_COMPARE (pthread_attr_getsigmask_np (&attr
, &set
),
126 PTHREAD_ATTR_NO_SIGMASK_NP
);
127 /* By default, the signal mask is inherited (even with an explicit
128 thread attribute). */
129 check_posix_thread (&attr
, (signals
) { [SIGUSR1
] = true, });
131 /* Check that pthread_attr_getsigmask_np can obtain the signal
134 sigaddset (&set
, SIGUSR2
);
135 TEST_COMPARE (pthread_attr_setsigmask_np (&attr
, &set
), 0);
137 TEST_COMPARE (pthread_attr_getsigmask_np (&attr
, &set
), 0);
138 check_sigmask ("pthread_attr_getsigmask_np", (signals
) { [SIGUSR2
] = true, },
141 /* Check that a thread is launched with the configured signal
143 check_current_sigmask ("SIGUSR1 masked", (signals
) { [SIGUSR1
] = true, });
144 check_posix_thread (&attr
, (signals
) { [SIGUSR2
] = true, });
145 check_current_sigmask ("SIGUSR1 masked", (signals
) { [SIGUSR1
] = true, });
147 /* But C11 threads remain at inheritance. */
148 check_c11_thread ((signals
) { [SIGUSR1
] = true, });
150 /* Check that filling the original signal set does not affect thread
153 check_posix_thread (&attr
, (signals
) { [SIGUSR2
] = true, });
155 /* Check that clearing the signal in the attribute restores
157 TEST_COMPARE (pthread_attr_setsigmask_np (&attr
, NULL
), 0);
158 TEST_COMPARE (pthread_attr_getsigmask_np (&attr
, &set
),
159 PTHREAD_ATTR_NO_SIGMASK_NP
);
160 check_posix_thread (&attr
, (signals
) { [SIGUSR1
] = true, });
162 /* Mask SIGHUP via the default thread attribute. */
164 sigaddset (&set
, SIGHUP
);
165 TEST_COMPARE (pthread_attr_setsigmask_np (&attr
, &set
), 0);
166 TEST_COMPARE (pthread_setattr_default_np (&attr
), 0);
168 /* Check that the mask was applied to the default attribute. */
169 xpthread_attr_destroy (&attr
);
170 TEST_COMPARE (pthread_getattr_default_np (&attr
), 0);
171 sigaddset (&set
, SIGHUP
);
172 TEST_COMPARE (pthread_attr_getsigmask_np (&attr
, &set
), 0);
173 check_sigmask ("default attribute", (signals
) { [SIGHUP
] = true, }, &set
);
174 xpthread_attr_destroy (&attr
);
176 /* Check that the default attribute is applied. */
177 check_posix_thread (NULL
, (signals
) { [SIGHUP
] = true, });
178 check_c11_thread ((signals
) { [SIGHUP
] = true, });
180 /* An explicit attribute with no signal mask triggers inheritance
181 even if the default has been changed. */
182 xpthread_attr_init (&attr
);
183 check_posix_thread (&attr
, (signals
) { [SIGUSR1
] = true, });
185 /* Explicitly setting the signal mask affects the new thread even
186 with a default attribute. */
188 sigaddset (&set
, SIGUSR2
);
189 TEST_COMPARE (pthread_attr_setsigmask_np (&attr
, &set
), 0);
190 check_posix_thread (&attr
, (signals
) { [SIGUSR2
] = true, });
192 /* Resetting the default attribute brings back the old inheritance
194 xpthread_attr_destroy (&attr
);
195 xpthread_attr_init (&attr
);
196 TEST_COMPARE (pthread_setattr_default_np (&attr
), 0);
197 xpthread_attr_destroy (&attr
);
198 check_posix_thread (NULL
, (signals
) { [SIGUSR1
] = true, });
199 check_c11_thread ((signals
) { [SIGUSR1
] = true, });
204 #include <support/test-driver.c>