From 058dc6d6cf91a52194344f4e9270a44f01058a4c Mon Sep 17 00:00:00 2001 From: David Leonard Date: Mon, 1 Feb 1999 08:48:32 +0000 Subject: move tests together --- lib/libc_r/TEST/test_sigsuspend.c | 237 +++++++++++++++++++++++++ lib/libc_r/TEST/test_sigwait.c | 262 ++++++++++++++++++++++++++++ lib/libc_r/test/Makefile | 8 - lib/libc_r/test/sigsuspend/Makefile | 8 - lib/libc_r/test/sigsuspend/sigsuspend.c | 273 ----------------------------- lib/libc_r/test/sigwait/Makefile | 8 - lib/libc_r/test/sigwait/sigwait.c | 295 -------------------------------- 7 files changed, 499 insertions(+), 592 deletions(-) create mode 100644 lib/libc_r/TEST/test_sigsuspend.c create mode 100644 lib/libc_r/TEST/test_sigwait.c delete mode 100644 lib/libc_r/test/Makefile delete mode 100644 lib/libc_r/test/sigsuspend/Makefile delete mode 100644 lib/libc_r/test/sigsuspend/sigsuspend.c delete mode 100644 lib/libc_r/test/sigwait/Makefile delete mode 100644 lib/libc_r/test/sigwait/sigwait.c (limited to 'lib') diff --git a/lib/libc_r/TEST/test_sigsuspend.c b/lib/libc_r/TEST/test_sigsuspend.c new file mode 100644 index 00000000000..da345f8d0bc --- /dev/null +++ b/lib/libc_r/TEST/test_sigsuspend.c @@ -0,0 +1,237 @@ +/* + * Copyright (c) 1998 Daniel M. Eischen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Daniel M. Eischen. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#include +#include + +#include +#include +#include +#include +#include + +#include +#include "test.h" + +static int sigcounts[NSIG + 1]; +static int sigfifo[NSIG + 1]; +static int fifo_depth = 0; +static sigset_t suspender_mask; +static pthread_t suspender_tid; + + +static void * +sigsuspender (void *arg) +{ + int save_count, status, i; + sigset_t run_mask; + + /* Run with all signals blocked. */ + sigfillset (&run_mask); + CHECKe(sigprocmask (SIG_SETMASK, &run_mask, NULL)); + + /* Allow these signals to wake us up during a sigsuspend. */ + sigfillset (&suspender_mask); /* Default action */ + sigdelset (&suspender_mask, SIGINT); /* terminate */ + sigdelset (&suspender_mask, SIGHUP); /* terminate */ + sigdelset (&suspender_mask, SIGQUIT); /* create core image */ + sigdelset (&suspender_mask, SIGURG); /* ignore */ + sigdelset (&suspender_mask, SIGIO); /* ignore */ + sigdelset (&suspender_mask, SIGUSR2); /* terminate */ + + while (sigcounts[SIGINT] == 0) { + save_count = sigcounts[SIGUSR2]; + + status = sigsuspend (&suspender_mask); + if ((status == 0) || (errno != EINTR)) { + DIE(errno, "Unable to suspend for signals, " + "return value %d\n", + status); + } + for (i = 0; i < fifo_depth; i++) + printf ("Sigsuspend woke up by signal %d (%s)\n", + sigfifo[i], strsignal(sigfifo[i])); + fifo_depth = 0; + } + + return (arg); +} + + +static void +sighandler (int signo) +{ + sigset_t set; + pthread_t self; + + if ((signo >= 0) && (signo <= NSIG)) + sigcounts[signo]++; + + /* + * If we are running on behalf of the suspender thread, + * ensure that we have the correct mask set. + */ + self = pthread_self (); + if (self == suspender_tid) { + sigfifo[fifo_depth] = signo; + fifo_depth++; + printf (" -> Suspender thread signal handler caught " + "signal %d (%s)\n", signo, strsignal(signo)); + sigprocmask (SIG_SETMASK, NULL, &set); + ASSERT(set == suspender_mask); + } + else + printf (" -> Main thread signal handler caught " + "signal %d (%s)\n", signo, strsignal(signo)); +} + + +int main (int argc, char *argv[]) +{ + pthread_attr_t pattr; + struct sigaction act; + sigset_t oldset; + sigset_t newset; + + /* Initialize our signal counts. */ + memset ((void *) sigcounts, 0, NSIG * sizeof (int)); + + /* Ignore signal SIGIO. */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGIO); + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + CHECKe(sigaction (SIGIO, &act, NULL)); + + /* Install a signal handler for SIGURG. */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGURG); + act.sa_handler = sighandler; + act.sa_flags = SA_RESTART; + CHECKe(sigaction (SIGURG, &act, NULL)); + + /* Install a signal handler for SIGXCPU */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGXCPU); + CHECKe(sigaction (SIGXCPU, &act, NULL)); + + /* Get our current signal mask. */ + CHECKe(sigprocmask (SIG_SETMASK, NULL, &oldset)); + + /* Mask out SIGUSR1 and SIGUSR2. */ + newset = oldset; + sigaddset (&newset, SIGUSR1); + sigaddset (&newset, SIGUSR2); + CHECKe(sigprocmask (SIG_SETMASK, &newset, NULL)); + + /* Install a signal handler for SIGUSR1 and SIGUSR2 */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGUSR1); + sigaddset (&act.sa_mask, SIGUSR2); + act.sa_handler = sighandler; + act.sa_flags = SA_RESTART; + CHECKe(sigaction (SIGUSR1, &act, NULL)); + CHECKe(sigaction (SIGUSR2, &act, NULL)); + + /* + * Initialize the thread attribute. + */ + CHECKr(pthread_attr_init (&pattr)); + CHECKr(pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE)); + + /* + * Create the sigsuspender thread. + */ + CHECKr(pthread_create (&suspender_tid, &pattr, sigsuspender, NULL)); + pthread_set_name_np (suspender_tid, "sigsuspender"); + + /* + * Verify that an ignored signal doesn't cause a wakeup. + * We don't have a handler installed for SIGIO. + */ + CHECKr(pthread_kill (suspender_tid, SIGIO)); + sleep (1); + CHECKe(kill (getpid (), SIGIO)); + sleep (1); + /* sigsuspend should not wake up for ignored signal SIGIO */ + ASSERT(sigcounts[SIGIO] == 0); + + /* + * Verify that a signal with a default action of ignore, for + * which we have a signal handler installed, will release a + * sigsuspend. + */ + CHECKr(pthread_kill (suspender_tid, SIGURG)); + sleep (1); + CHECKe(kill (getpid (), SIGURG)); + sleep (1); + /* sigsuspend should wake up for SIGURG */ + ASSERT(sigcounts[SIGURG] == 3); + + /* + * Verify that a SIGUSR2 signal will release a sigsuspended + * thread. + */ + CHECKr(pthread_kill (suspender_tid, SIGUSR2)); + sleep (1); + CHECKe(kill (getpid (), SIGUSR2)); + sleep (1); + /* sigsuspend should wake yp for SIGUSR2 */ + ASSERT(sigcounts[SIGUSR2] == 2); + + /* + * Verify that a signal, blocked in both the main and + * sigsuspender threads, does not cause the signal handler + * to be called. + */ + CHECKr(pthread_kill (suspender_tid, SIGUSR1)); + sleep (1); + CHECKe(kill (getpid (), SIGUSR1)); + sleep (1); + /* signal handler should not be called for USR1 */ + ASSERT(sigcounts[SIGUSR1] == 0); +#if 0 + /* + * Verify that we can still kill the process for a signal + * not being waited on by sigwait. + */ + CHECKe(kill (getpid (), SIGPIPE)); + PANIC("SIGPIPE did not terminate process"); + + /* + * Wait for the thread to finish. + */ + CHECKr(pthread_join (suspender_tid, NULL)); +#endif + SUCCEED; +} + diff --git a/lib/libc_r/TEST/test_sigwait.c b/lib/libc_r/TEST/test_sigwait.c new file mode 100644 index 00000000000..2f0f66619aa --- /dev/null +++ b/lib/libc_r/TEST/test_sigwait.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 1998 Daniel M. Eischen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Daniel M. Eischen. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#include +#include + +#include +#include +#include +#include +#include + +#include +#include "test.h" + +static int sigcounts[NSIG + 1]; +static sigset_t wait_mask; +static pthread_mutex_t waiter_mutex; + + +static void * +sigwaiter (void *arg) +{ + int signo; + sigset_t mask; + + /* Block SIGHUP */ + sigemptyset (&mask); + sigaddset (&mask, SIGHUP); + CHECKe(sigprocmask (SIG_BLOCK, &mask, NULL)); + + while (sigcounts[SIGINT] == 0) { + printf("Sigwait waiting (thread %p)\n", pthread_self()); + CHECKe(sigwait (&wait_mask, &signo)); + sigcounts[signo]++; + printf ("Sigwait caught signal %d (%s)\n", signo, + strsignal(signo)); + + /* Allow the main thread to prevent the sigwait. */ + CHECKr(pthread_mutex_lock (&waiter_mutex)); + CHECKr(pthread_mutex_unlock (&waiter_mutex)); + } + + return (arg); +} + + +static void +sighandler (int signo) +{ + printf (" -> Signal handler caught signal %d (%s) in thread %p\n", + signo, strsignal(signo), pthread_self()); + + if ((signo >= 0) && (signo <= NSIG)) + sigcounts[signo]++; +} + +int main (int argc, char *argv[]) +{ + pthread_mutexattr_t mattr; + pthread_attr_t pattr; + pthread_t tid; + struct sigaction act; + + /* Initialize our signal counts. */ + memset ((void *) sigcounts, 0, NSIG * sizeof (int)); + + /* Setupt our wait mask. */ + sigemptyset (&wait_mask); /* Default action */ + sigaddset (&wait_mask, SIGHUP); /* terminate */ + sigaddset (&wait_mask, SIGINT); /* terminate */ + sigaddset (&wait_mask, SIGQUIT); /* create core image */ + sigaddset (&wait_mask, SIGURG); /* ignore */ + sigaddset (&wait_mask, SIGIO); /* ignore */ + sigaddset (&wait_mask, SIGUSR1); /* terminate */ + + /* Ignore signals SIGHUP and SIGIO. */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGHUP); + sigaddset (&act.sa_mask, SIGIO); + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + CHECKe(sigaction (SIGHUP, &act, NULL)); + CHECKe(sigaction (SIGIO, &act, NULL)); + + /* Install a signal handler for SIGURG */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGURG); + act.sa_handler = sighandler; + act.sa_flags = SA_RESTART; + CHECKe(sigaction (SIGURG, &act, NULL)); + + /* Install a signal handler for SIGXCPU */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGXCPU); + CHECKe(sigaction (SIGXCPU, &act, NULL)); + + /* + * Initialize the thread attribute. + */ + CHECKr(pthread_attr_init (&pattr)); + CHECKr(pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE)); + + /* + * Initialize and create a mutex. + */ + CHECKr(pthread_mutexattr_init (&mattr)); + CHECKr(pthread_mutex_init (&waiter_mutex, &mattr)); + + /* + * Create the sigwaiter thread. + */ + CHECKr(pthread_create (&tid, &pattr, sigwaiter, NULL)); + pthread_set_name_np (tid, "sigwaiter"); + + /* + * Verify that an ignored signal doesn't cause a wakeup. + * We don't have a handler installed for SIGIO. + */ + CHECKr(pthread_kill (tid, SIGIO)); + sleep (1); + CHECKe(kill(getpid(), SIGIO)); + sleep (1); + /* sigwait should not wake up for ignored signal SIGIO */ + ASSERT(sigcounts[SIGIO] == 0); + + /* + * Verify that a signal with a default action of ignore, for + * which we have a signal handler installed, will release a sigwait. + */ + CHECKr(pthread_kill (tid, SIGURG)); + sleep (1); + CHECKe(kill(getpid(), SIGURG)); + sleep (1); + /* sigwait should wake up for SIGURG */ + ASSERT(sigcounts[SIGURG] == 2); + + /* + * Verify that a signal with a default action that terminates + * the process will release a sigwait. + */ + CHECKr(pthread_kill (tid, SIGUSR1)); + sleep (1); + CHECKe(kill(getpid(), SIGUSR1)); + sleep (1); + if (sigcounts[SIGUSR1] != 2) + printf ("FAIL: sigwait doesn't wake up for SIGUSR1.\n"); + + /* + * Verify that if we install a signal handler for a previously + * ignored signal, an occurrence of this signal will release + * the (already waiting) sigwait. + */ + + /* Install a signal handler for SIGHUP. */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGHUP); + act.sa_handler = sighandler; + act.sa_flags = SA_RESTART; + CHECKe(sigaction (SIGHUP, &act, NULL)); + + /* Sending SIGHUP should release the sigwait. */ + CHECKe(kill(getpid(), SIGHUP)); + sleep (1); + CHECKr(pthread_kill (tid, SIGHUP)); + sleep (1); + /* sigwait should wake up for SIGHUP */ + ASSERT(sigcounts[SIGHUP] == 2); + + /* + * Verify that a pending signal in the waiters mask will + * cause sigwait to return the pending signal. We do this + * by taking the waiters mutex and signaling the waiter to + * release him from the sigwait. The waiter will block + * on taking the mutex, and we can then send the waiter a + * signal which should be added to his pending signals. + * The next time the waiter does a sigwait, he should + * return with the pending signal. + */ + sigcounts[SIGHUP] = 0; + CHECKr(pthread_mutex_lock (&waiter_mutex)); + /* Release the waiter from sigwait. */ + CHECKe(kill(getpid(), SIGHUP)); + sleep (1); + /* sigwait should wake up for SIGHUP */ + ASSERT(sigcounts[SIGHUP] == 1); + /* + * Add SIGHUP to all threads pending signals. Since there is + * a signal handler installed for SIGHUP and this signal is + * blocked from the waiter thread and unblocked in the main + * thread, the signal handler should be called once for SIGHUP. + */ + CHECKe(kill(getpid(), SIGHUP)); + /* Release the waiter thread and allow him to run. */ + CHECKr(pthread_mutex_unlock (&waiter_mutex)); + sleep (1); + /* sigwait should return for pending SIGHUP */ + ASSERT(sigcounts[SIGHUP] == 3); + + /* + * Repeat the above test using pthread_kill and SIGUSR1 + */ + sigcounts[SIGUSR1] = 0; + CHECKr(pthread_mutex_lock (&waiter_mutex)); + /* Release the waiter from sigwait. */ + CHECKr(pthread_kill (tid, SIGUSR1)); + sleep (1); + /* sigwait should wake up for SIGUSR1 */ + ASSERT(sigcounts[SIGUSR1] == 1); + /* Add SIGHUP to the waiters pending signals. */ + CHECKr(pthread_kill (tid, SIGUSR1)); + /* Release the waiter thread and allow him to run. */ + CHECKe(pthread_mutex_unlock (&waiter_mutex)); + sleep (1); + /* sigwait should return for pending SIGUSR1 */ + ASSERT(sigcounts[SIGUSR1] == 2); + +#if 0 + /* + * Verify that we can still kill the process for a signal + * not being waited on by sigwait. + */ + CHECKe(kill(getpid(), SIGPIPE)); + PANIC("SIGPIPE did not terminate process"); + + /* + * Wait for the thread to finish. + */ + CHECKr(pthread_join (tid, NULL)); +#endif + + SUCCEED; +} diff --git a/lib/libc_r/test/Makefile b/lib/libc_r/test/Makefile deleted file mode 100644 index e5962f61357..00000000000 --- a/lib/libc_r/test/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# $Id: Makefile,v 1.1 1998/11/09 03:13:17 d Exp $ -# -# Tests for libc_r functionality. -# - -SUBDIR= sigsuspend sigwait - -.include diff --git a/lib/libc_r/test/sigsuspend/Makefile b/lib/libc_r/test/sigsuspend/Makefile deleted file mode 100644 index 796ffdf97e1..00000000000 --- a/lib/libc_r/test/sigsuspend/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# $Id: Makefile,v 1.1 1998/11/09 03:13:17 d Exp $ - -PROG= sigsuspend -SRCS= sigsuspend.c -NOMAN= 1 -LDFLAGS= -pthread - -.include diff --git a/lib/libc_r/test/sigsuspend/sigsuspend.c b/lib/libc_r/test/sigsuspend/sigsuspend.c deleted file mode 100644 index 894b0926333..00000000000 --- a/lib/libc_r/test/sigsuspend/sigsuspend.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (c) 1998 Daniel M. Eischen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel M. Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ -#include -#include - -#include -#include -#include -#include -#include - -#if defined(__FreeBSD__) -#include -#endif - -static int sigcounts[NSIG + 1]; -static int sigfifo[NSIG + 1]; -static int fifo_depth = 0; -static sigset_t suspender_mask; -static pthread_t suspender_tid; - - -static void * -sigsuspender (void *arg) -{ - int save_count, status, i; - sigset_t run_mask; - - /* Run with all signals blocked. */ - sigfillset (&run_mask); - sigprocmask (SIG_SETMASK, &run_mask, NULL); - - /* Allow these signals to wake us up during a sigsuspend. */ - sigfillset (&suspender_mask); /* Default action */ - sigdelset (&suspender_mask, SIGINT); /* terminate */ - sigdelset (&suspender_mask, SIGHUP); /* terminate */ - sigdelset (&suspender_mask, SIGQUIT); /* create core image */ - sigdelset (&suspender_mask, SIGURG); /* ignore */ - sigdelset (&suspender_mask, SIGIO); /* ignore */ - sigdelset (&suspender_mask, SIGUSR2); /* terminate */ - - while (sigcounts[SIGINT] == 0) { - save_count = sigcounts[SIGUSR2]; - - status = sigsuspend (&suspender_mask); - if ((status == 0) || (errno != EINTR)) { - printf ("Unable to suspend for signals, " - "errno %d, return value %d\n", - errno, status); - exit (1); - } - for (i = 0; i < fifo_depth; i++) - printf ("Sigsuspend woke up by signal %d\n", - sigfifo[i]); - fifo_depth = 0; - } - - pthread_exit (arg); - return (NULL); -} - - -static void -sighandler (int signo) -{ - sigset_t set; - pthread_t self; - - if ((signo >= 0) && (signo <= NSIG)) - sigcounts[signo]++; - - /* - * If we are running on behalf of the suspender thread, - * ensure that we have the correct mask set. - */ - self = pthread_self (); - if (self == suspender_tid) { - sigfifo[fifo_depth] = signo; - fifo_depth++; - printf (" -> Suspender thread signal handler caught signal %d\n", - signo); - sigprocmask (SIG_SETMASK, NULL, &set); - if (set != suspender_mask) - printf (" >>> FAIL: sigsuspender signal handler running " - "with incorrect mask.\n"); - } - else - printf (" -> Main thread signal handler caught signal %d\n", - signo); -} - - -static void -send_thread_signal (pthread_t tid, int signo) -{ - if (pthread_kill (tid, signo) != 0) { - printf ("Unable to send thread signal, errno %d.\n", errno); - exit (1); - } -} - - -static void -send_process_signal (int signo) -{ - if (kill (getpid (), signo) != 0) { - printf ("Unable to send process signal, errno %d.\n", errno); - exit (1); - } -} - - -int main (int argc, char *argv[]) -{ - pthread_attr_t pattr; - void * exit_status; - struct sigaction act; - sigset_t oldset; - sigset_t newset; - - /* Initialize our signal counts. */ - memset ((void *) sigcounts, 0, NSIG * sizeof (int)); - - /* Ignore signal SIGIO. */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGIO); - act.sa_handler = SIG_IGN; - act.sa_flags = 0; - sigaction (SIGIO, &act, NULL); - - /* Install a signal handler for SIGURG. */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGURG); - act.sa_handler = sighandler; - act.sa_flags = SA_RESTART; - sigaction (SIGURG, &act, NULL); - - /* Install a signal handler for SIGXCPU */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGXCPU); - sigaction (SIGXCPU, &act, NULL); - - /* Get our current signal mask. */ - sigprocmask (SIG_SETMASK, NULL, &oldset); - - /* Mask out SIGUSR1 and SIGUSR2. */ - newset = oldset; - sigaddset (&newset, SIGUSR1); - sigaddset (&newset, SIGUSR2); - sigprocmask (SIG_SETMASK, &newset, NULL); - - /* Install a signal handler for SIGUSR1 and SIGUSR2 */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGUSR1); - sigaddset (&act.sa_mask, SIGUSR2); - act.sa_handler = sighandler; - act.sa_flags = SA_RESTART; - sigaction (SIGUSR1, &act, NULL); - sigaction (SIGUSR2, &act, NULL); - - /* - * Initialize the thread attribute. - */ - if ((pthread_attr_init (&pattr) != 0) || - (pthread_attr_setdetachstate (&pattr, - PTHREAD_CREATE_JOINABLE) != 0)) { - printf ("Unable to initialize thread attributes.\n"); - exit (1); - } - - /* - * Create the sigsuspender thread. - */ - if (pthread_create (&suspender_tid, &pattr, sigsuspender, NULL) != 0) { - printf ("Unable to create thread, errno %d.\n", errno); - exit (1); - } -#if defined(__FreeBSD__) - pthread_set_name_np (suspender_tid, "sigsuspender"); -#endif - - /* - * Verify that an ignored signal doesn't cause a wakeup. - * We don't have a handler installed for SIGIO. - */ - send_thread_signal (suspender_tid, SIGIO); - sleep (1); - send_process_signal (SIGIO); - sleep (1); - if (sigcounts[SIGIO] != 0) - printf ("FAIL: sigsuspend wakes up for ignored signal " - "SIGIO.\n"); - - /* - * Verify that a signal with a default action of ignore, for - * which we have a signal handler installed, will release a - * sigsuspend. - */ - send_thread_signal (suspender_tid, SIGURG); - sleep (1); - send_process_signal (SIGURG); - sleep (1); - if (sigcounts[SIGURG] != 3) - printf ("FAIL: sigsuspend doesn't wake up for SIGURG.\n"); - - /* - * Verify that a SIGUSR2 signal will release a sigsuspended - * thread. - */ - send_thread_signal (suspender_tid, SIGUSR2); - sleep (1); - send_process_signal (SIGUSR2); - sleep (1); - if (sigcounts[SIGUSR2] != 2) - printf ("FAIL: sigsuspend doesn't wake up for SIGUSR2.\n"); - - /* - * Verify that a signal, blocked in both the main and - * sigsuspender threads, does not cause the signal handler - * to be called. - */ - send_thread_signal (suspender_tid, SIGUSR1); - sleep (1); - send_process_signal (SIGUSR1); - sleep (1); - if (sigcounts[SIGUSR1] != 0) - printf ("FAIL: signal hander called for SIGUSR1.\n"); - - /* - * Verify that we can still kill the process for a signal - * not being waited on by sigwait. - */ - send_process_signal (SIGPIPE); - printf ("FAIL: SIGPIPE did not terminate process.\n"); - - /* - * Wait for the thread to finish. - */ - pthread_join (suspender_tid, &exit_status); - - return (0); -} - diff --git a/lib/libc_r/test/sigwait/Makefile b/lib/libc_r/test/sigwait/Makefile deleted file mode 100644 index 86f70c9a4ab..00000000000 --- a/lib/libc_r/test/sigwait/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# $Id: Makefile,v 1.1 1998/11/09 03:13:18 d Exp $ - -PROG= sigwait -SRCS= sigwait.c -NOMAN= 1 -LDFLAGS= -pthread - -.include diff --git a/lib/libc_r/test/sigwait/sigwait.c b/lib/libc_r/test/sigwait/sigwait.c deleted file mode 100644 index 6dd31087a6e..00000000000 --- a/lib/libc_r/test/sigwait/sigwait.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (c) 1998 Daniel M. Eischen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel M. Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ -#include -#include - -#include -#include -#include -#include -#include - -#if defined(__FreeBSD__) -#include -#endif - -static int sigcounts[NSIG + 1]; -static sigset_t wait_mask; -static pthread_mutex_t waiter_mutex; - - -static void * -sigwaiter (void *arg) -{ - int signo; - sigset_t mask; - - /* Block SIGHUP */ - sigemptyset (&mask); - sigaddset (&mask, SIGHUP); - sigprocmask (SIG_BLOCK, &mask, NULL); - - while (sigcounts[SIGINT] == 0) { - if (sigwait (&wait_mask, &signo) != 0) { - printf ("Unable to wait for signal, errno %d\n", - errno); - exit (1); - } - sigcounts[signo]++; - printf ("Sigwait caught signal %d\n", signo); - - /* Allow the main thread to prevent the sigwait. */ - pthread_mutex_lock (&waiter_mutex); - pthread_mutex_unlock (&waiter_mutex); - } - - pthread_exit (arg); - return (NULL); -} - - -static void -sighandler (int signo) -{ - printf (" -> Signal handler caught signal %d\n", signo); - - if ((signo >= 0) && (signo <= NSIG)) - sigcounts[signo]++; -} - -static void -send_thread_signal (pthread_t tid, int signo) -{ - if (pthread_kill (tid, signo) != 0) { - printf ("Unable to send thread signal, errno %d.\n", errno); - exit (1); - } -} - -static void -send_process_signal (int signo) -{ - if (kill (getpid (), signo) != 0) { - printf ("Unable to send process signal, errno %d.\n", errno); - exit (1); - } -} - - -int main (int argc, char *argv[]) -{ - pthread_mutexattr_t mattr; - pthread_attr_t pattr; - pthread_t tid; - void * exit_status; - struct sigaction act; - - /* Initialize our signal counts. */ - memset ((void *) sigcounts, 0, NSIG * sizeof (int)); - - /* Setupt our wait mask. */ - sigemptyset (&wait_mask); /* Default action */ - sigaddset (&wait_mask, SIGHUP); /* terminate */ - sigaddset (&wait_mask, SIGINT); /* terminate */ - sigaddset (&wait_mask, SIGQUIT); /* create core image */ - sigaddset (&wait_mask, SIGURG); /* ignore */ - sigaddset (&wait_mask, SIGIO); /* ignore */ - sigaddset (&wait_mask, SIGUSR1); /* terminate */ - - /* Ignore signals SIGHUP and SIGIO. */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGHUP); - sigaddset (&act.sa_mask, SIGIO); - act.sa_handler = SIG_IGN; - act.sa_flags = 0; - sigaction (SIGHUP, &act, NULL); - sigaction (SIGIO, &act, NULL); - - /* Install a signal handler for SIGURG */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGURG); - act.sa_handler = sighandler; - act.sa_flags = SA_RESTART; - sigaction (SIGURG, &act, NULL); - - /* Install a signal handler for SIGXCPU */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGXCPU); - sigaction (SIGXCPU, &act, NULL); - - /* - * Initialize the thread attribute. - */ - if ((pthread_attr_init (&pattr) != 0) || - (pthread_attr_setdetachstate (&pattr, - PTHREAD_CREATE_JOINABLE) != 0)) { - printf ("Unable to initialize thread attributes.\n"); - exit (1); - } - - /* - * Initialize and create a mutex. - */ - if ((pthread_mutexattr_init (&mattr) != 0) || - (pthread_mutex_init (&waiter_mutex, &mattr) != 0)) { - printf ("Unable to create waiter mutex.\n"); - exit (1); - } - - /* - * Create the sigwaiter thread. - */ - if (pthread_create (&tid, &pattr, sigwaiter, NULL) != 0) { - printf ("Unable to create thread.\n"); - exit (1); - } -#if defined(__FreeBSD__) - pthread_set_name_np (tid, "sigwaiter"); -#endif - - /* - * Verify that an ignored signal doesn't cause a wakeup. - * We don't have a handler installed for SIGIO. - */ - send_thread_signal (tid, SIGIO); - sleep (1); - send_process_signal (SIGIO); - sleep (1); - if (sigcounts[SIGIO] != 0) - printf ("FAIL: sigwait wakes up for ignored signal SIGIO.\n"); - - /* - * Verify that a signal with a default action of ignore, for - * which we have a signal handler installed, will release a sigwait. - */ - send_thread_signal (tid, SIGURG); - sleep (1); - send_process_signal (SIGURG); - sleep (1); - if (sigcounts[SIGURG] != 2) - printf ("FAIL: sigwait doesn't wake up for SIGURG.\n"); - - /* - * Verify that a signal with a default action that terminates - * the process will release a sigwait. - */ - send_thread_signal (tid, SIGUSR1); - sleep (1); - send_process_signal (SIGUSR1); - sleep (1); - if (sigcounts[SIGUSR1] != 2) - printf ("FAIL: sigwait doesn't wake up for SIGUSR1.\n"); - - /* - * Verify that if we install a signal handler for a previously - * ignored signal, an occurrence of this signal will release - * the (already waiting) sigwait. - */ - - /* Install a signal handler for SIGHUP. */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGHUP); - act.sa_handler = sighandler; - act.sa_flags = SA_RESTART; - sigaction (SIGHUP, &act, NULL); - - /* Sending SIGHUP should release the sigwait. */ - send_process_signal (SIGHUP); - sleep (1); - send_thread_signal (tid, SIGHUP); - sleep (1); - if (sigcounts[SIGHUP] != 2) - printf ("FAIL: sigwait doesn't wake up for SIGHUP.\n"); - - /* - * Verify that a pending signal in the waiters mask will - * cause sigwait to return the pending signal. We do this - * by taking the waiters mutex and signaling the waiter to - * release him from the sigwait. The waiter will block - * on taking the mutex, and we can then send the waiter a - * signal which should be added to his pending signals. - * The next time the waiter does a sigwait, he should - * return with the pending signal. - */ - sigcounts[SIGHUP] = 0; - pthread_mutex_lock (&waiter_mutex); - /* Release the waiter from sigwait. */ - send_process_signal (SIGHUP); - sleep (1); - if (sigcounts[SIGHUP] != 1) - printf ("FAIL: sigwait doesn't wake up for SIGHUP.\n"); - /* - * Add SIGHUP to all threads pending signals. Since there is - * a signal handler installed for SIGHUP and this signal is - * blocked from the waiter thread and unblocked in the main - * thread, the signal handler should be called once for SIGHUP. - */ - send_process_signal (SIGHUP); - /* Release the waiter thread and allow him to run. */ - pthread_mutex_unlock (&waiter_mutex); - sleep (1); - if (sigcounts[SIGHUP] != 3) - printf ("FAIL: sigwait doesn't return for pending SIGHUP.\n"); - - /* - * Repeat the above test using pthread_kill and SIGUSR1 - */ - sigcounts[SIGUSR1] = 0; - pthread_mutex_lock (&waiter_mutex); - /* Release the waiter from sigwait. */ - send_thread_signal (tid, SIGUSR1); - sleep (1); - if (sigcounts[SIGUSR1] != 1) - printf ("FAIL: sigwait doesn't wake up for SIGUSR1.\n"); - /* Add SIGHUP to the waiters pending signals. */ - send_thread_signal (tid, SIGUSR1); - /* Release the waiter thread and allow him to run. */ - pthread_mutex_unlock (&waiter_mutex); - sleep (1); - if (sigcounts[SIGUSR1] != 2) - printf ("FAIL: sigwait doesn't return for pending SIGUSR1.\n"); - - /* - * Verify that we can still kill the process for a signal - * not being waited on by sigwait. - */ - send_process_signal (SIGPIPE); - printf ("FAIL: SIGPIPE did not terminate process.\n"); - - /* - * Wait for the thread to finish. - */ - pthread_join (tid, &exit_status); - - return (0); -} -- cgit v1.2.3