X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=functions%2Fsignal%2Fraise.c;h=51c787a2db16da958b3658c8040f924bdd4a9674;hb=d7f375a09a9912bb18ad42f1442fbf64311bfed6;hp=29afe151f9b611d6fe0f5f776aa88b5f16496e60;hpb=01c88bc38e78e9b2c47917b85b9b497187946e3c;p=pdclib diff --git a/functions/signal/raise.c b/functions/signal/raise.c index 29afe15..51c787a 100644 --- a/functions/signal/raise.c +++ b/functions/signal/raise.c @@ -1,5 +1,3 @@ -/* $Id$ */ - /* raise( int ) This file is part of the Public Domain C Library (PDCLib). @@ -10,6 +8,9 @@ #ifndef REGTEST +#include +#include + extern void (*_PDCLIB_sigabrt)( int ); extern void (*_PDCLIB_sigfpe)( int ); extern void (*_PDCLIB_sigill)( int ); @@ -19,31 +20,48 @@ extern void (*_PDCLIB_sigterm)( int ); int raise( int sig ) { + void (*sighandler)( int ); + char const * message; switch ( sig ) { case SIGABRT: - _PDCLIB_sigabrt( sig ); + sighandler = _PDCLIB_sigabrt; + message = "Abnormal termination (SIGABRT)"; break; case SIGFPE: - _PDCLIB_sigfpe( sig ); + sighandler = _PDCLIB_sigfpe; + message = "Arithmetic exception (SIGFPE)"; break; case SIGILL: - _PDCLIB_sigill( sig ); + sighandler = _PDCLIB_sigill; + message = "Illegal instruction (SIGILL)"; break; case SIGINT: - _PDCLIB_sigint( sig ); + sighandler = _PDCLIB_sigint; + message = "Interactive attention signal (SIGINT)"; break; case SIGSEGV: - _PDCLIB_sigsegv( sig ); + sighandler = _PDCLIB_sigsegv; + message = "Invalid memory access (SIGSEGV)"; break; case SIGTERM: - _PDCLIB_sigterm( sig ); + sighandler = _PDCLIB_sigterm; + message = "Termination request (SIGTERM)"; break; default: - /* TODO: Implement. */ - break; + fprintf( stderr, "Unknown signal #%d\n", sig ); + _Exit( EXIT_FAILURE ); + } + if ( sighandler == SIG_DFL ) + { + fputs( message, stderr ); + _Exit( EXIT_FAILURE ); + } + else if ( sighandler != SIG_IGN ) + { + sighandler = signal( sig, SIG_DFL ); + sighandler( sig ); } - /* TODO: Implement. */ return 0; } @@ -52,9 +70,43 @@ int raise( int sig ) #ifdef TEST #include <_PDCLIB_test.h> +#include + +static volatile sig_atomic_t flag = 0; + +static int expected_signal = 0; + +static void test_handler( int sig ) +{ + TESTCASE( sig == expected_signal ); + flag = 1; +} + int main( void ) { - TESTCASE( NO_TESTDRIVER ); + /* Could be other than SIG_DFL if you changed the implementation. */ + TESTCASE( signal( SIGABRT, SIG_IGN ) == SIG_DFL ); + /* Should be ignored. */ + TESTCASE( raise( SIGABRT ) == 0 ); + /* Installing test handler, old handler should be returned */ + TESTCASE( signal( SIGABRT, test_handler ) == SIG_IGN ); + /* Raising and checking SIGABRT */ + expected_signal = SIGABRT; + TESTCASE( raise( SIGABRT ) == 0 ); + TESTCASE( flag == 1 ); + /* Re-installing test handler, should have been reset to default */ + /* Could be other than SIG_DFL if you changed the implementation. */ + TESTCASE( signal( SIGABRT, test_handler ) == SIG_DFL ); + /* Raising and checking SIGABRT */ + flag = 0; + TESTCASE( raise( SIGABRT ) == 0 ); + TESTCASE( flag == 1 ); + /* Installing test handler for different signal... */ + TESTCASE( signal( SIGTERM, test_handler ) == SIG_DFL ); + /* Raising and checking SIGTERM */ + expected_signal = SIGTERM; + TESTCASE( raise( SIGTERM ) == 0 ); + TESTCASE( flag == 1 ); return TEST_RESULTS; } #endif