]> pd.if.org Git - pdclib/blob - platform/example/functions/signal/raise.c
On C++, define _PDCLIB_wchar_t to be builtin type wchar_t
[pdclib] / platform / example / functions / signal / raise.c
1 /* $Id$ */
2
3 /* raise( int )
4
5    This file is part of the Public Domain C Library (PDCLib).
6    Permission is granted to use, modify, and / or redistribute at will.
7 */
8
9 #include <signal.h>
10
11 #ifndef REGTEST
12
13 #include <stdio.h>
14 #include <stdlib.h>
15
16 extern void (*_PDCLIB_sigabrt)( int );
17 extern void (*_PDCLIB_sigfpe)( int );
18 extern void (*_PDCLIB_sigill)( int );
19 extern void (*_PDCLIB_sigint)( int );
20 extern void (*_PDCLIB_sigsegv)( int );
21 extern void (*_PDCLIB_sigterm)( int );
22
23 int raise( int sig )
24 {
25     void (*sighandler)( int );
26     char const * message;
27     switch ( sig )
28     {
29         case SIGABRT:
30             sighandler = _PDCLIB_sigabrt;
31             message = "Abnormal termination (SIGABRT)";
32             break;
33         case SIGFPE:
34             sighandler = _PDCLIB_sigfpe;
35             message = "Arithmetic exception (SIGFPE)";
36             break;
37         case SIGILL:
38             sighandler = _PDCLIB_sigill;
39             message = "Illegal instruction (SIGILL)";
40             break;
41         case SIGINT:
42             sighandler = _PDCLIB_sigint;
43             message = "Interactive attention signal (SIGINT)";
44             break;
45         case SIGSEGV:
46             sighandler = _PDCLIB_sigsegv;
47             message = "Invalid memory access (SIGSEGV)";
48             break;
49         case SIGTERM:
50             sighandler = _PDCLIB_sigterm;
51             message = "Termination request (SIGTERM)";
52             break;
53         default:
54             fprintf( stderr, "Unknown signal #%d\n", sig );
55             _Exit( EXIT_FAILURE );
56     }
57     if ( sighandler == SIG_DFL )
58     {
59         fputs( message, stderr );
60         _Exit( EXIT_FAILURE );
61     }
62     else if ( sighandler != SIG_IGN )
63     {
64         sighandler = signal( sig, SIG_DFL );
65         sighandler( sig );
66     }
67     return 0;
68 }
69
70 #endif
71
72 #ifdef TEST
73 #include <_PDCLIB_test.h>
74
75 #include <stdlib.h>
76
77 static volatile sig_atomic_t flag = 0;
78
79 static int expected_signal = 0;
80
81 static void test_handler( int sig )
82 {
83     TESTCASE( sig == expected_signal );
84     flag = 1;
85 }
86
87 int main( void )
88 {
89     /* Could be other than SIG_DFL if you changed the implementation. */
90     TESTCASE( signal( SIGABRT, SIG_IGN ) == SIG_DFL );
91     /* Should be ignored. */
92     TESTCASE( raise( SIGABRT ) == 0 );
93     /* Installing test handler, old handler should be returned */
94     TESTCASE( signal( SIGABRT, test_handler ) == SIG_IGN );
95     /* Raising and checking SIGABRT */
96     expected_signal = SIGABRT;
97     TESTCASE( raise( SIGABRT ) == 0 );
98     TESTCASE( flag == 1 );
99     /* Re-installing test handler, should have been reset to default */
100     /* Could be other than SIG_DFL if you changed the implementation. */
101     TESTCASE( signal( SIGABRT, test_handler ) == SIG_DFL );
102     /* Raising and checking SIGABRT */
103     flag = 0;
104     TESTCASE( raise( SIGABRT ) == 0 );
105     TESTCASE( flag == 1 );
106     /* Installing test handler for different signal... */
107     TESTCASE( signal( SIGTERM, test_handler ) == SIG_DFL );
108     /* Raising and checking SIGTERM */
109     expected_signal = SIGTERM;
110     TESTCASE( raise( SIGTERM ) == 0 );
111     TESTCASE( flag == 1 );
112     return TEST_RESULTS;
113 }
114 #endif