/* * Copyright (c) 2003, Intel Corporation. All rights reserved. * Created by: salwan.searty REMOVE-THIS AT intel DOT com * This file is licensed under the GPL license. For the full content * of this license, see the COPYING file at the top level of this * source tree. The resulting set shall be the the signal set pointed to by set Steps: 1. Have main create a new thread and wait for its termination. 2. Inside the new thread, set up the signal mask such that it contains only SIGABRT (by passing SIG_SETMASK value to pthread_sigmask) 4. Raise SIGABRT, and make sure that the handler associated with it wasn't executed, otherwise fail. 5. Also make sure that SIGABRT is pending, otherwise fail. * patch * 5b. Change mask to SIGUSR1 and check that the handler is called. This means that SIG_SETMASK removed the old signal from the set. * /patch * 6. Pass one of three return codes to the main() function: - A value of -1 if SIGABRT wasn't found pending or causes the handler to be executed. - A value of 0 if SIGABRT was in fact pending and the handler wasn't executed. - A value of 1 incase of any UNRESOLVED situation such as an unexpected function failure. */ #include #include #include #include "posixtest.h" int handler_called = 0; void handler( int signo ) { handler_called = 1; } void *a_thread_func() { struct sigaction act; sigset_t blocked_set, pending_set; sigemptyset( &blocked_set ); sigaddset( &blocked_set, SIGABRT ); act.sa_handler = handler; act.sa_flags = 0; sigemptyset( &act.sa_mask ); if ( sigaction( SIGABRT, &act, 0 ) == -1 ) { perror( "Unexpected error while attempting to setup test " "pre-conditions" ); pthread_exit( ( void* ) 1 ); } if ( pthread_sigmask( SIG_SETMASK, &blocked_set, NULL ) == -1 ) { perror( "Unexpected error while attempting to use pthread_sigmask.\n" ); pthread_exit( ( void* ) 1 ); } if ( raise( SIGABRT ) == -1 ) { perror( "Unexpected error while attempting to setup test " "pre-conditions" ); pthread_exit( ( void* ) 1 ); } if ( handler_called ) { printf( "FAIL: Signal was not blocked\n" ); pthread_exit( ( void* ) - 1 ); } if ( sigpending( &pending_set ) == -1 ) { perror( "Unexpected error while attempting to use sigpending\n" ); pthread_exit( ( void* ) 1 ); } if ( sigismember( &pending_set, SIGABRT ) == -1 ) { perror( "Unexpected error while attempting to use sigismember.\n" ); pthread_exit( ( void* ) - 1 ); } if ( sigismember( &pending_set, SIGABRT ) != 1 ) { perror( "FAIL: sigismember did not return 1\n" ); pthread_exit( ( void* ) 1 ); } sigemptyset( &blocked_set ); sigaddset( &blocked_set, SIGUSR1 ); if ( pthread_sigmask( SIG_SETMASK, &blocked_set, NULL ) == -1 ) { perror( "Unexpected error while attempting to use pthread_sigmask.\n" ); pthread_exit( ( void* ) 1 ); } sched_yield(); if ( !handler_called ) { printf( "FAIL: Old signal was not removed from mask.\n" ); pthread_exit( ( void* ) - 1 ); } pthread_exit( ( void* ) 0 ); return NULL; } int main() { int * thread_return_value; pthread_t new_thread; if ( pthread_create( &new_thread, NULL, a_thread_func, NULL ) != 0 ) { perror( "Error creating new thread\n" ); return PTS_UNRESOLVED; } if ( pthread_join( new_thread, ( void* ) & thread_return_value ) != 0 ) { perror( "Error in pthread_join()\n" ); return PTS_UNRESOLVED; } if ( ( long ) thread_return_value != 0 ) { if ( ( long ) thread_return_value == 1 ) { printf ( "Test UNRESOLVED\n" ); return PTS_UNRESOLVED; } else if ( ( long ) thread_return_value == -1 ) { printf ( "Test FAILED\n" ); return PTS_FAIL; } else { printf ( "Test UNRESOLVED\n" ); return PTS_UNRESOLVED; } } printf( "Test PASSED\n" ); return PTS_PASS; }