summaryrefslogtreecommitdiff
path: root/src/pal/tests/palsuite/threading/SetConsoleCtrlHandler/test8/test8.c
blob: 1c3ee2b71de0ac1ae0bae9efaa348f8c7e5612f4 (plain)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information. 
//

/*=============================================================================
**
** Source: test8.c
**
** Dependencies: PAL_Initialize
**               PAL_Terminate
**               GenerateConsoleCtrlEvent
**
** Purpose:
**
** Test to ensure proper operation of the SetConsoleCtrlHandler()
** API by attempting to add and remove the same handler multiple
** times.
** 

**
**===========================================================================*/
#include <palsuite.h>



/* the number of times to set the console control handler function */
#define HANDLER_SET_COUNT 5



/* the number of times the console control handler function's been called */
static int g_count = 0;




/* to avoid having the default control handler abort our process */
static BOOL PALAPI FinalCtrlHandler( DWORD CtrlType )
{
    return (CtrlType == CTRL_C_EVENT);
}


/* test handler function */
static BOOL PALAPI CtrlHandler1( DWORD CtrlType ) 
{ 
    if( CtrlType == CTRL_C_EVENT )
    {
        ++g_count;
    }

    return FALSE;
}





/* main entry point function */
int __cdecl main( int argc, char **argv ) 

{
    /* local variables */
    int     i;
    BOOL    ret = PASS;
    BOOL    bSetFinalHandler = FALSE;
    int     nSetCount = 0;


    /* PAL initialization */
    if( (PAL_Initialize(argc, argv)) != 0 )
    {
        return( FAIL );
    }


    /* set our final console control handler function */
    if( SetConsoleCtrlHandler( FinalCtrlHandler, TRUE ) )
    {
        bSetFinalHandler = TRUE;
    }
    else
    {
        ret = FAIL;
        Trace( "ERROR:%lu:SetConsoleCtrlHandler() failed to add "
                "FinalCtrlHandler\n",
                GetLastError() );
        Fail( "Test failed\n" );
    }
    
    /* try to set our test handler multiple times */
    for( i=0; i<HANDLER_SET_COUNT; i++ )
    {
        if( SetConsoleCtrlHandler( CtrlHandler1, TRUE ) )
        {
            nSetCount++;
        }
        else
        {
            ret = FAIL;
            Trace( "ERROR:%lu:SetConsoleCtrlHandler() failed to add "
                    "CtrlHandler1 at attempt #%d\n",
                    GetLastError(),
                    i );
            goto done;
        }
    }

    /* loop here -- generate an event and verify that our handler */
    /* was called the correct number of times, then unset it one  */
    /* time and repeat until it's completely unset.               */
    for( ; nSetCount>0; nSetCount-- )
    {
        /* test that the control handler functions are set */
        if( ! GenerateConsoleCtrlEvent( CTRL_C_EVENT, 0 ) )
        {
            Trace( "ERROR:%lu:GenerateConsoleCtrlEvent() failed\n",
                    GetLastError() );
            ret = FAIL;
            goto done;
        }
    
        /* give the handlers a chance to execute */    
        Sleep( 2000 );
        
        /* check the results */
        if( g_count != nSetCount )
        {
            Trace( "ERROR:CtrlHandler1() was not called %d times, "
                    "expected %d\n",
                    g_count,
                    nSetCount );
            ret = FAIL;
            goto done;
        }
        
        /* unset the control handler one time */
        if( ! SetConsoleCtrlHandler( CtrlHandler1, FALSE ) )
        {
            ret = FAIL;
            Trace( "ERROR:%lu:SetConsoleCtrlHandler() failed to "
                    "remove CtrlHandler instance #%d\n",
                    GetLastError(),
                    nSetCount );
            Fail( "Test failed\n" );
        }
        
        /* reset our counter */
        g_count = 0;
    }
    
    
    
done:
    /* unset any lingering instances of our test control handler */
    for( ; nSetCount>0; nSetCount-- )
    {
        /* unset the control handler one time */
        if( ! SetConsoleCtrlHandler( CtrlHandler1, FALSE ) )
        {
            ret = FAIL;
            Trace( "ERROR:%lu:SetConsoleCtrlHandler() failed to "
                    "remove CtrlHandler instance #%d\n",
                    GetLastError(),
                    nSetCount );
            Fail( "Test failed\n" );
        }
    }
    
    
    /* unset our final control handler if it was set */
    if( bSetFinalHandler )
    {
        if( ! SetConsoleCtrlHandler( FinalCtrlHandler, FALSE ) )
        {
            ret = FAIL;
            Trace( "ERROR:%lu:SetConsoleCtrlHandler() failed to "
                    "remove FinalCtrlHandler\n",
                    GetLastError() );
            Fail( "Test failed\n" );
        }
    }
    
    
    /* PAL termination */
    PAL_TerminateEx(ret);

    
    /* return our result */
    return ret;
}