From 8798372261ed1df999bc9f4f3f0be0a230480041 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 10 Sep 2019 12:53:31 -0500 Subject: Correct initial POSIX signals mask + Modify POSIX thread create extension to ensure expected initial signal mask is provided to system threads, initial tasks and threads, and inheritied by tasks and threads. + Adds psxsignal07 to verify functionality when using a POSIX Initialization thread and POSIX threads. + Adds psxsignal08 to verify functionality when using a Classic API Initialization task and Classic API tasks. Closes #3794. --- testsuites/psxtests/Makefile.am | 22 ++++ testsuites/psxtests/configure.ac | 2 + testsuites/psxtests/psxsignal01/init.c | 14 ++ testsuites/psxtests/psxsignal02/init.c | 14 ++ testsuites/psxtests/psxsignal03/init.c | 14 ++ testsuites/psxtests/psxsignal07/main.c | 136 ++++++++++++++++++++ testsuites/psxtests/psxsignal07/psxsignal07.doc | 23 ++++ testsuites/psxtests/psxsignal07/psxsignal07.scn | 7 + testsuites/psxtests/psxsignal07/rtems_config.c | 44 +++++++ testsuites/psxtests/psxsignal08/main.c | 163 ++++++++++++++++++++++++ testsuites/psxtests/psxsignal08/psxsignal08.doc | 22 ++++ testsuites/psxtests/psxsignal08/psxsignal08.scn | 7 + testsuites/psxtests/psxsignal08/rtems_config.c | 45 +++++++ 13 files changed, 513 insertions(+) create mode 100644 testsuites/psxtests/psxsignal07/main.c create mode 100644 testsuites/psxtests/psxsignal07/psxsignal07.doc create mode 100644 testsuites/psxtests/psxsignal07/psxsignal07.scn create mode 100644 testsuites/psxtests/psxsignal07/rtems_config.c create mode 100644 testsuites/psxtests/psxsignal08/main.c create mode 100644 testsuites/psxtests/psxsignal08/psxsignal08.doc create mode 100644 testsuites/psxtests/psxsignal08/psxsignal08.scn create mode 100644 testsuites/psxtests/psxsignal08/rtems_config.c (limited to 'testsuites/psxtests') diff --git a/testsuites/psxtests/Makefile.am b/testsuites/psxtests/Makefile.am index 2ccb10a473..536b77f560 100755 --- a/testsuites/psxtests/Makefile.am +++ b/testsuites/psxtests/Makefile.am @@ -881,6 +881,28 @@ psxsignal06_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_psxsignal06) \ endif endif +if HAS_POSIX +if TEST_psxsignal07 +psx_tests += psxsignal07 +psx_screens += psxsignal07/psxsignal07.scn +psx_docs += psxsignal07/psxsignal07.doc +psxsignal07_SOURCES = psxsignal07/main.c psxsignal07/rtems_config.c +psxsignal07_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_psxsignal07) \ + $(support_includes) -I$(top_srcdir)/include +endif +endif + +if HAS_POSIX +if TEST_psxsignal08 +psx_tests += psxsignal08 +psx_screens += psxsignal08/psxsignal08.scn +psx_docs += psxsignal08/psxsignal08.doc +psxsignal08_SOURCES = psxsignal08/main.c psxsignal08/rtems_config.c +psxsignal08_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_psxsignal08) \ + $(support_includes) -I$(top_srcdir)/include +endif +endif + if TEST_psxspin01 psx_tests += psxspin01 psx_screens += psxspin01/psxspin01.scn diff --git a/testsuites/psxtests/configure.ac b/testsuites/psxtests/configure.ac index 6e2b19f498..139787cccb 100644 --- a/testsuites/psxtests/configure.ac +++ b/testsuites/psxtests/configure.ac @@ -135,6 +135,8 @@ RTEMS_TEST_CHECK([psxsignal03]) RTEMS_TEST_CHECK([psxsignal04]) RTEMS_TEST_CHECK([psxsignal05]) RTEMS_TEST_CHECK([psxsignal06]) +RTEMS_TEST_CHECK([psxsignal07]) +RTEMS_TEST_CHECK([psxsignal08]) RTEMS_TEST_CHECK([psxspin01]) RTEMS_TEST_CHECK([psxstack01]) RTEMS_TEST_CHECK([psxstack02]) diff --git a/testsuites/psxtests/psxsignal01/init.c b/testsuites/psxtests/psxsignal01/init.c index 511dd2d637..6df3695c98 100644 --- a/testsuites/psxtests/psxsignal01/init.c +++ b/testsuites/psxtests/psxsignal01/init.c @@ -36,6 +36,18 @@ extern void _POSIX_signals_Abnormal_termination_handler( int signo ); volatile int Signal_occurred; volatile int Signal_count; +static void block_all_signals(void) +{ + int sc; + sigset_t mask; + + sc = sigfillset( &mask ); + rtems_test_assert( !sc ); + + sc = pthread_sigmask( SIG_BLOCK, &mask, NULL ); + rtems_test_assert( !sc ); +} + void Handler_1( int signo ) @@ -108,6 +120,8 @@ void *POSIX_Init( TEST_BEGIN(); + block_all_signals(); + /* set the time of day, and print our buffer in multiple ways */ set_time( TM_FRIDAY, TM_MAY, 24, 96, 11, 5, 0 ); diff --git a/testsuites/psxtests/psxsignal02/init.c b/testsuites/psxtests/psxsignal02/init.c index 1f9afc9fca..c7a9432415 100644 --- a/testsuites/psxtests/psxsignal02/init.c +++ b/testsuites/psxtests/psxsignal02/init.c @@ -28,6 +28,18 @@ void Install_Signal_Handler(const char *task_name); volatile bool Signal_occurred; volatile pthread_t Signal_thread; +static void block_all_signals(void) +{ + int sc; + sigset_t mask; + + sc = sigfillset( &mask ); + rtems_test_assert( !sc ); + + sc = pthread_sigmask( SIG_BLOCK, &mask, NULL ); + rtems_test_assert( !sc ); +} + void Signal_handler( int signo ) @@ -140,6 +152,8 @@ void *POSIX_Init( Signal_occurred = false; + block_all_signals(); + act.sa_handler = Signal_handler; act.sa_flags = 0; sigaction( SIGUSR1, &act, NULL ); diff --git a/testsuites/psxtests/psxsignal03/init.c b/testsuites/psxtests/psxsignal03/init.c index b51ff36313..fcf7192664 100644 --- a/testsuites/psxtests/psxsignal03/init.c +++ b/testsuites/psxtests/psxsignal03/init.c @@ -64,6 +64,18 @@ const char *signal_name(int signo); volatile bool Signal_occurred; volatile pthread_t Signal_thread; +static void block_all_signals(void) +{ + int sc; + sigset_t mask; + + sc = sigfillset( &mask ); + rtems_test_assert( !sc ); + + sc = pthread_sigmask( SIG_BLOCK, &mask, NULL ); + rtems_test_assert( !sc ); +} + void Signal_handler( int signo, siginfo_t *info, @@ -166,6 +178,8 @@ void *POSIX_Init( TEST_BEGIN(); puts( "Init - Variation is: " TEST_STRING ); + block_all_signals(); + Signal_occurred = false; act.sa_handler = NULL; diff --git a/testsuites/psxtests/psxsignal07/main.c b/testsuites/psxtests/psxsignal07/main.c new file mode 100644 index 0000000000..52b21751c8 --- /dev/null +++ b/testsuites/psxtests/psxsignal07/main.c @@ -0,0 +1,136 @@ +/* + * @brief psxsignal07 - Ensure initial signal mask and thread inheritance + */ + +/* + * COPYRIGHT (c) 2019. + * On-Line Applications Research Corporation (OAR). + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "test_support.h" +#include +#include +#include + +const char rtems_test_name[] = "PSXSIGNAL 7"; + +static sigset_t main_sigmask; + +#define SIGSET_NBYTES (sizeof(sigset_t)) + +/* #define DEBUG_TEST */ + +static void fetch_sigmask(const char *name, sigset_t *sigset_p) +{ + int rc; + + rc = sigemptyset(sigset_p); + rtems_test_assert(rc == 0); + + rc = sigprocmask(SIG_SETMASK, NULL, sigset_p); + rtems_test_assert(rc == 0); + +#ifdef DEBUG_TEST + /* + * There is no assurance that sigset_t is a primitive type so + * we have to print it a long at a time. + */ + int i; + unsigned char *p = (unsigned char *) sigset_p; + + printf("%s signal mask (in hex):\n ", name); + for (i=0 ; i < SIGSET_NBYTES ; i++) { + printf("%02x%s", *p++, (i % 16 == 15) ? "\n " : " "); + } + printf("\n"); +#endif +} + +static void block_sigmask(int signo, sigset_t *sigset_p) +{ + sigset_t sigset; + int rc; + + /* + * Block the requested signal + */ + rc = sigemptyset(&sigset); + rtems_test_assert(rc == 0); + rc = sigaddset(&sigset, signo); + rtems_test_assert(rc == 0); + + rc = sigprocmask(SIG_BLOCK, &sigset, NULL); + rtems_test_assert(rc == 0); + + /* + * Fetch the current signal mask reflecting the requested update + */ + sigemptyset(sigset_p); + rc = sigprocmask(SIG_SETMASK, NULL, sigset_p); + rtems_test_assert(rc == 0); +} + +static void *thread_body(void *arg) +{ + sigset_t mask; + + /* + * There is no assurance that sigset_t is a primitive type so + * we have to use memcmp(). + */ + fetch_sigmask("main", &main_sigmask); + fetch_sigmask(arg, &mask); + rtems_test_assert(main_sigmask == mask); + + return NULL; +} + +int main(int argc, char **argv) +{ + int rc; + pthread_t id; + sigset_t empty; + + TEST_BEGIN(); + + /* + * Verify first thread has empty signal mask + */ + fetch_sigmask("main", &main_sigmask); + + sigemptyset(&empty); + fetch_sigmask("empty", &empty); + + puts("Ensure main thread's mask equals sigemptyset"); + rtems_test_assert(main_sigmask == empty); + + /* + * Verify first thread has empty signal mask + */ + puts("Ensure parent's empty mask is inherited by thread"); + rc = pthread_create(&id, NULL, thread_body, "thread1"); + rtems_test_assert(rc == 0); + sleep(1); + + /* + * Create a thread and see if it inherits non-empty signal mask. + */ + puts("Ensure parent's mask with SIGUSR1 mask is inherited by thread"); + block_sigmask(SIGUSR1, &main_sigmask); + rc = pthread_create(&id, NULL, thread_body, "thread2"); + rtems_test_assert(rc == 0); + sleep(1); + + TEST_END(); + + rtems_test_exit(0); + return 0; +} + diff --git a/testsuites/psxtests/psxsignal07/psxsignal07.doc b/testsuites/psxtests/psxsignal07/psxsignal07.doc new file mode 100644 index 0000000000..78425471f7 --- /dev/null +++ b/testsuites/psxtests/psxsignal07/psxsignal07.doc @@ -0,0 +1,23 @@ +# COPYRIGHT (c) 2019. +# On-Line Applications Research Corporation (OAR). +# +# SPDX-License-Identifier: BSD-2-Clause +# + +This file describes the directives and concepts tested by this test set. + +test set name: psxsignal07 + +directives: + + sigprocmask + sigemptyset + sigaddset + +concepts: + ++ Ensure that the initial signal mask is empty (all unmasked). + ++ Ensure that a POSIX thread inherits an empty signal mask. + ++ Ensure that a POSIX thread inherits an non-empty signal mask. diff --git a/testsuites/psxtests/psxsignal07/psxsignal07.scn b/testsuites/psxtests/psxsignal07/psxsignal07.scn new file mode 100644 index 0000000000..ad7a12deda --- /dev/null +++ b/testsuites/psxtests/psxsignal07/psxsignal07.scn @@ -0,0 +1,7 @@ +*** BEGIN OF TEST PSXSIGNAL 7 *** +Ensure main thread's mask equals sigemptyset +Ensure parent's empty mask is inherited by thread +Ensure parent's mask with SIGUSR1 mask is inherited by thread + +*** END OF TEST PSXSIGNAL 7 *** + diff --git a/testsuites/psxtests/psxsignal07/rtems_config.c b/testsuites/psxtests/psxsignal07/rtems_config.c new file mode 100644 index 0000000000..e3f3349640 --- /dev/null +++ b/testsuites/psxtests/psxsignal07/rtems_config.c @@ -0,0 +1,44 @@ +/* + * COPYRIGHT (c) 2019. + * On-Line Applications Research Corporation (OAR). + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +int main(int argc, char **argv); + +static char *argv_list[] = { + "psxsignal07", + "" +}; +static void *POSIX_Init(void *arg) +{ + (void) arg; /* deliberately ignored */ + + /* + * Initialize optional services + */ + + /* + * Could get arguments from command line or have a static set. + */ + (void) main(1, argv_list); + + return NULL; +} + +#include /* for device driver prototypes */ + +/* NOTICE: the clock driver is explicitly disabled */ +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + +#define CONFIGURE_POSIX_INIT_THREAD_TABLE + +#define CONFIGURE_UNLIMITED_OBJECTS +#define CONFIGURE_UNIFIED_WORK_AREAS + +#define CONFIGURE_INIT +#include diff --git a/testsuites/psxtests/psxsignal08/main.c b/testsuites/psxtests/psxsignal08/main.c new file mode 100644 index 0000000000..c55a7712b9 --- /dev/null +++ b/testsuites/psxtests/psxsignal08/main.c @@ -0,0 +1,163 @@ +/* + * @brief psxsignal08 - Ensure initial signal mask and Classic Task inheritance + */ + +/* + * COPYRIGHT (c) 2019. + * On-Line Applications Research Corporation (OAR). + * + * SPDX-License-Identifier: BSD-2-Clause + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "test_support.h" +#include +#include +#include + +#include + +const char rtems_test_name[] = "PSXSIGNAL 8"; + +static sigset_t main_sigmask; + +#define SIGSET_NBYTES (sizeof(sigset_t)) + +/* #define DEBUG_TEST */ + +static void fetch_sigmask(const char *name, sigset_t *sigset_p) +{ + int rc; + + rc = sigemptyset(sigset_p); + rtems_test_assert(rc == 0); + + rc = sigprocmask(SIG_SETMASK, NULL, sigset_p); + rtems_test_assert(rc == 0); + +#ifdef DEBUG_TEST + /* + * There is no assurance that sigset_t is a primitive type so + * we have to print it a long at a time. + */ + int i; + unsigned char *p = (unsigned char *) sigset_p; + + printf("%s signal mask (in hex):\n ", name); + for (i=0 ; i < SIGSET_NBYTES ; i++) { + printf("%02x%s", *p++, (i % 16 == 15) ? "\n " : " "); + } + printf("\n"); +#endif +} + +static void block_sigmask(int signo, sigset_t *sigset_p) +{ + sigset_t sigset; + int rc; + + /* + * Block the requested signal + */ + rc = sigemptyset(&sigset); + rtems_test_assert(rc == 0); + rc = sigaddset(&sigset, signo); + rtems_test_assert(rc == 0); + + rc = sigprocmask(SIG_BLOCK, &sigset, NULL); + rtems_test_assert(rc == 0); + + /* + * Fetch the current signal mask reflecting the requested update + */ + sigemptyset(sigset_p); + rc = sigprocmask(SIG_SETMASK, NULL, sigset_p); + rtems_test_assert(rc == 0); +} + +static rtems_task task_body(rtems_task_argument arg) +{ + sigset_t mask; + + /* + * There is no assurance that sigset_t is a primitive type so + * we have to use memcmp(). + */ + fetch_sigmask("main", &main_sigmask); + fetch_sigmask((void *)arg, &mask); + rtems_test_assert(main_sigmask == mask); + + (void) rtems_task_delete(RTEMS_SELF); +} + +int main(int argc, char **argv) +{ + sigset_t empty; + rtems_status_code status; + rtems_id id; + + TEST_BEGIN(); + + /* + * Verify first task has empty signal mask + */ + fetch_sigmask("main", &main_sigmask); + + sigemptyset(&empty); + fetch_sigmask("empty", &empty); + + puts("Ensure main task's mask equals sigemptyset"); + rtems_test_assert(main_sigmask == empty); + + /* + * Create a task and see if it inherits empty signal mask. + */ + puts("Ensure parent's empty mask is inherited by thread"); + status = rtems_task_create( + rtems_build_name( 'T', 'A', '1', ' ' ), + 1, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &id + ); + directive_failed( status, "rtems_task_create" ); + + status = rtems_task_start( id, task_body, 1 ); + directive_failed( status, "rtems_task_start" ); + + sleep(1); + + /* + * Create a task and see if it inherits non-empty signal mask. + */ + puts("Ensure parent's mask with SIGUSR1 mask is inherited by thread"); + block_sigmask(SIGUSR1, &main_sigmask); + + status = rtems_task_create( + rtems_build_name( 'T', 'A', '1', ' ' ), + 1, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &id + ); + directive_failed( status, "rtems_task_create" ); + + status = rtems_task_start( id, task_body, 1 ); + directive_failed( status, "rtems_task_start" ); + + sleep(1); + + + TEST_END(); + + rtems_test_exit(0); + return 0; +} + diff --git a/testsuites/psxtests/psxsignal08/psxsignal08.doc b/testsuites/psxtests/psxsignal08/psxsignal08.doc new file mode 100644 index 0000000000..f476996fad --- /dev/null +++ b/testsuites/psxtests/psxsignal08/psxsignal08.doc @@ -0,0 +1,22 @@ +# COPYRIGHT (c) 2019. +# On-Line Applications Research Corporation (OAR). +# +# SPDX-License-Identifier: BSD-2-Clause + +This file describes the directives and concepts tested by this test set. + +test set name: psxsignal07 + +directives: + + sigprocmask + sigemptyset + sigaddset + +concepts: + ++ Ensure that the initial signal mask is empty (all unmasked). + ++ Ensure that a Classic API task inherits an empty signal mask. + ++ Ensure that a Classic API task inherits an non-empty signal mask. diff --git a/testsuites/psxtests/psxsignal08/psxsignal08.scn b/testsuites/psxtests/psxsignal08/psxsignal08.scn new file mode 100644 index 0000000000..6aa8ce8e39 --- /dev/null +++ b/testsuites/psxtests/psxsignal08/psxsignal08.scn @@ -0,0 +1,7 @@ +** BEGIN OF TEST PSXSIGNAL 8 *** +Ensure main task's mask equals sigemptyset +Ensure parent's empty mask is inherited by thread +Ensure parent's mask with SIGUSR1 mask is inherited by thread + +*** END OF TEST PSXSIGNAL 8 *** + diff --git a/testsuites/psxtests/psxsignal08/rtems_config.c b/testsuites/psxtests/psxsignal08/rtems_config.c new file mode 100644 index 0000000000..f56e88c8be --- /dev/null +++ b/testsuites/psxtests/psxsignal08/rtems_config.c @@ -0,0 +1,45 @@ +/* + * COPYRIGHT (c) 2019. + * On-Line Applications Research Corporation (OAR). + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +int main(int argc, char **argv); + +static char *argv_list[] = { + "report", + "" +}; +static rtems_task Init(rtems_task_argument arg) +{ + (void) arg; /* deliberately ignored */ + + /* + * Initialize optional services + */ + + /* + * Could get arguments from command line or have a static set. + */ + (void) main(1, argv_list); + + exit(0); +} + +#include /* for device driver prototypes */ + +/* NOTICE: the clock driver is explicitly disabled */ +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_UNLIMITED_OBJECTS +#define CONFIGURE_UNIFIED_WORK_AREAS + +#define CONFIGURE_INIT +#include -- cgit v1.2.3