File: raise.c

package info (click to toggle)
libconvert-binary-c-perl 0.86-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,264 kB
  • sloc: ansic: 47,836; perl: 4,980; yacc: 2,143; makefile: 61
file content (135 lines) | stat: -rw-r--r-- 3,468 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* raise( int )

   This file is part of the Public Domain C Library (PDCLib).
   Permission is granted to use, modify, and / or redistribute at will.
*/

#include <signal.h>

#ifndef REGTEST

#include <stdio.h>
#include <stdlib.h>

extern void ( *_PDCLIB_sigabrt )( int );
extern void ( *_PDCLIB_sigfpe )( int );
extern void ( *_PDCLIB_sigill )( int );
extern void ( *_PDCLIB_sigint )( int );
extern void ( *_PDCLIB_sigsegv )( int );
extern void ( *_PDCLIB_sigterm )( int );

int raise( int sig )
{
    void ( *sighandler )( int );
    const char * message;

    switch ( sig )
    {
        case SIGABRT:
            sighandler = _PDCLIB_sigabrt;
            message = "Abnormal termination (SIGABRT)";
            break;

        case SIGFPE:
            sighandler = _PDCLIB_sigfpe;
            message = "Arithmetic exception (SIGFPE)";
            break;

        case SIGILL:
            sighandler = _PDCLIB_sigill;
            message = "Illegal instruction (SIGILL)";
            break;

        case SIGINT:
            sighandler = _PDCLIB_sigint;
            message = "Interactive attention signal (SIGINT)";
            break;

        case SIGSEGV:
            sighandler = _PDCLIB_sigsegv;
            message = "Invalid memory access (SIGSEGV)";
            break;

        case SIGTERM:
            sighandler = _PDCLIB_sigterm;
            message = "Termination request (SIGTERM)";
            break;

        default:
            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 )
    {
        /* FIXME: "The implementation shall behave as if no library function
           calls the signal function."
        */
        sighandler = signal( sig, SIG_DFL );
        sighandler( sig );
    }

    return 0;
}

#endif

#ifdef TEST

#include "_PDCLIB_test.h"

#include <stdlib.h>

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 )
{
    void ( *sighandler )( int );
    /* Could be other than SIG_DFL if you changed the implementation. */
    sighandler = signal( SIGABRT, SIG_IGN );
#ifndef REGTEST
    TESTCASE( sighandler == SIG_DFL );
#endif
    /* 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. */
    sighandler = signal( SIGABRT, test_handler );
#ifndef REGTEST
    TESTCASE( sighandler == SIG_DFL );
#endif
    /* 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 );
    /* void expression to avoid "unused" warning in regtest */
    (void)sighandler;
    return TEST_RESULTS;
}

#endif