From: Bruno Haible Date: Wed, 15 Apr 2026 11:45:58 +0000 (+0200) Subject: sigdelay: Add tests. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;ds=sidebyside;p=thirdparty%2Fgnulib.git sigdelay: Add tests. * 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. --- diff --git a/ChangeLog b/ChangeLog index b1079e902d..761d1edc0c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2026-04-15 Bruno Haible + sigdelay: Add tests. + * 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. + sigdelay: New module. * lib/sigdelay.h: New file. * lib/sigdelay.c: New file. diff --git a/modules/sigdelay-tests b/modules/sigdelay-tests new file mode 100644 index 0000000000..2c56ff4ba5 --- /dev/null +++ b/modules/sigdelay-tests @@ -0,0 +1,20 @@ +Files: +tests/test-sigdelay1.c +tests/test-sigdelay2.c +tests/virtualbox.h +tests/macros.h + +Depends-on: +inttypes-h +sleep +pthread-thread +streq +memeq + +configure.ac: + +Makefile.am: +TESTS += test-sigdelay1 test-sigdelay2 +check_PROGRAMS += test-sigdelay1 test-sigdelay2 +test_sigdelay1_LDADD = $(LDADD) @LIBTHREAD@ +test_sigdelay2_LDADD = $(LDADD) @LIBMULTITHREAD@ diff --git a/tests/test-sigdelay1.c b/tests/test-sigdelay1.c new file mode 100644 index 0000000000..a6b3e4b54f --- /dev/null +++ b/tests/test-sigdelay1.c @@ -0,0 +1,104 @@ +/* Test of sigdelay in a single-threaded program. + Copyright (C) 2011-2026 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2026. */ + +#include + +/* Specification. */ +#include "sigdelay.h" + +#include +#include +#include +#include +#include +#include + +#include "virtualbox.h" +#include "macros.h" + +#if !(defined _WIN32 && !defined __CYGWIN__) + +static volatile int sigint_occurred; + +static void +sigint_handler (_GL_UNUSED int sig) +{ + sigint_occurred++; +} + +int +main () +{ + /* This test occasionally fails on Linux (glibc or musl libc), in a + VirtualBox VM with paravirtualization = Default or KVM, with ≥ 2 CPUs, + when "Nested VT-x/AMD-V" and "PAE/NX" are not both enabled. + Skip the test in this situation. */ + if (is_running_under_virtualbox_kvm () && num_cpus () > 1) + { + fputs ("Skipping test: avoiding VirtualBox bug with KVM paravirtualization\n", + stderr); + return 77; + } + + signal (SIGINT, sigint_handler); + + sigset_t set; + sigemptyset (&set); + sigaddset (&set, SIGINT); + + /* Check error handling. */ + ASSERT (sigdelay (1729, &set, NULL) == -1); + ASSERT (errno == EINVAL); + + /* Block SIGINT. */ + ASSERT (sigdelay (SIG_BLOCK, &set, NULL) == 0); + + /* Request a SIGINT signal from outside. */ + char command[80]; + intmax_t pid = getpid (); + sprintf (command, "sh -c 'sleep 1; kill -INT %"PRIdMAX"' &", pid); + ASSERT (system (command) == 0); + + /* Wait. */ + sleep (2); + + /* The signal should not have arrived yet, because it is blocked. */ + ASSERT (sigint_occurred == 0); + + /* Unblock SIGINT. */ + ASSERT (sigdelay (SIG_UNBLOCK, &set, NULL) == 0); + + /* The signal should have arrived now. */ + ASSERT (sigint_occurred == 1); + + return test_exit_status; +} + +#else + +/* On native Windows, getpid() values and the arguments that are passed to + the (Cygwin?) 'kill' program are not necessarily related. */ + +int +main () +{ + fputs ("Skipping test: native Windows platform\n", stderr); + return 77; +} + +#endif diff --git a/tests/test-sigdelay2.c b/tests/test-sigdelay2.c new file mode 100644 index 0000000000..7d15d6de5b --- /dev/null +++ b/tests/test-sigdelay2.c @@ -0,0 +1,143 @@ +/* Test of sigdelay in a multi-threaded process. + Copyright (C) 2011-2026 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2026. */ + +#include + +/* Specification. */ +#include "sigdelay.h" + +#include +#include +#include +#include +#include + +#include "virtualbox.h" +#include "macros.h" + +#if USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS + +static pthread_t main_thread; +static pthread_t killer_thread1; +static pthread_t killer_thread2; + +static void * +killer_thread1_func (_GL_UNUSED void *arg) +{ + sleep (1); + pthread_kill (main_thread, SIGINT); + return NULL; +} + +static void * +killer_thread2_func (_GL_UNUSED void *arg) +{ + sleep (1); + pthread_kill (pthread_self (), SIGINT); + return NULL; +} + +static volatile int sigint_occurred; + +static void +sigint_handler (_GL_UNUSED int sig) +{ + sigint_occurred++; +} + +int +main () +{ + /* This test occasionally fails on Linux (glibc or musl libc), in a + VirtualBox VM with paravirtualization = Default or KVM, with ≥ 2 CPUs, + when "Nested VT-x/AMD-V" and "PAE/NX" are not both enabled. + Skip the test in this situation. */ + if (is_running_under_virtualbox_kvm () && num_cpus () > 1) + { + fputs ("Skipping test: avoiding VirtualBox bug with KVM paravirtualization\n", + stderr); + return 77; + } + + signal (SIGINT, sigint_handler); + + sigset_t set; + sigemptyset (&set); + sigaddset (&set, SIGINT); + + /* Check error handling. */ + ASSERT (sigdelay (1729, &set, NULL) == -1); + ASSERT (errno == EINVAL); + + /* Block SIGINT. */ + ASSERT (sigdelay (SIG_BLOCK, &set, NULL) == 0); + + /* Request a SIGINT signal from another thread. */ + main_thread = pthread_self (); + ASSERT (pthread_create (&killer_thread1, NULL, killer_thread1_func, NULL) + == 0); + + /* Wait. */ + sleep (2); + + /* The signal should not have arrived yet, because it is blocked. */ + ASSERT (sigint_occurred == 0); + + /* Unblock SIGINT. */ + ASSERT (sigdelay (SIG_UNBLOCK, &set, NULL) == 0); + + /* The signal should have arrived now. */ + ASSERT (sigint_occurred == 1); + + /* Request a SIGINT signal from another thread. */ + ASSERT (pthread_create (&killer_thread2, NULL, killer_thread2_func, NULL) + == 0); + + /* Block SIGINT. */ + ASSERT (sigdelay (SIG_BLOCK, &set, NULL) == 0); + + /* Wait. */ + sleep (2); + + /* The signal should not have arrived yet, because it is blocked. */ + ASSERT (sigint_occurred == 1); + + /* Unblock SIGINT. */ + ASSERT (sigdelay (SIG_UNBLOCK, &set, NULL) == 0); + + /* The signal should have arrived now. */ + ASSERT (sigint_occurred == 2); + + /* Clean up the threads. This avoids a "ThreadSanitizer: thread leak" warning + from "gcc -fsanitize=thread". */ + ASSERT (pthread_join (killer_thread1, NULL) == 0); + ASSERT (pthread_join (killer_thread2, NULL) == 0); + + return test_exit_status; +} + +#else + +int +main () +{ + fputs ("Skipping test: POSIX threads not enabled\n", stderr); + return 77; +} + +#endif