/* * @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; }