Home | History | Annotate | Download | only in templates
      1 /*
      2 * Copyright (c) 2005, Bull S.A..  All rights reserved.
      3 * Created by: Sebastien Decugis
      4 
      5 * This program is free software; you can redistribute it and/or modify it
      6 * under the terms of version 2 of the GNU General Public License as
      7 * published by the Free Software Foundation.
      8 *
      9 * This program is distributed in the hope that it would be useful, but
     10 * WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     12 *
     13 * You should have received a copy of the GNU General Public License along
     14 * with this program; if not, write the Free Software Foundation, Inc.,
     15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     16 
     17 
     18 * This sample test aims to check the following assertions:
     19 *
     20 * If SA_NODEFER is not set in sa_flags, the caught signal is added to the
     21 * thread's signal mask during the handler execution.
     22 
     23 * The steps are:
     24 * -> register a signal handler for %%MYSIG%%
     25 * -> raise %%MYSIG%%
     26 * -> In handler, check for reentrance then raise %%MYSIG%% again.
     27 
     28 * The test fails if signal handler if reentered or signal is not pending when raised again.
     29 */
     30 
     31 
     32 /* We are testing conformance to IEEE Std 1003.1, 2003 Edition */
     33 #define _POSIX_C_SOURCE 200112L
     34 
     35 /******************************************************************************/
     36 /*************************** standard includes ********************************/
     37 /******************************************************************************/
     38 #include <pthread.h>
     39 #include <stdarg.h>
     40 #include <stdio.h>
     41 #include <stdlib.h>
     42 #include <string.h>
     43 #include <unistd.h>
     44 
     45 #include <signal.h>
     46 #include <errno.h>
     47 
     48 /******************************************************************************/
     49 /***************************   Test framework   *******************************/
     50 /******************************************************************************/
     51 #include "testfrmw.h"
     52 #include "testfrmw.c"
     53 /* This header is responsible for defining the following macros:
     54  * UNRESOLVED(ret, descr);
     55  *    where descr is a description of the error and ret is an int
     56  *   (error code for example)
     57  * FAILED(descr);
     58  *    where descr is a short text saying why the test has failed.
     59  * PASSED();
     60  *    No parameter.
     61  *
     62  * Both three macros shall terminate the calling process.
     63  * The testcase shall not terminate in any other maneer.
     64  *
     65  * The other file defines the functions
     66  * void output_init()
     67  * void output(char * string, ...)
     68  *
     69  * Those may be used to output information.
     70  */
     71 
     72 /******************************************************************************/
     73 /**************************** Configuration ***********************************/
     74 /******************************************************************************/
     75 #ifndef VERBOSE
     76 #define VERBOSE 1
     77 #endif
     78 
     79 #define SIGNAL %%MYSIG%%
     80 
     81 /******************************************************************************/
     82 /***************************    Test case   ***********************************/
     83 /******************************************************************************/
     84 
     85 int called = 0;
     86 
     87 void handler( int sig )
     88 {
     89 	int ret;
     90 	sigset_t pending;
     91 	called++;
     92 
     93 	if ( called == 2 )
     94 	{
     95 		FAILED( "Signal was not masked in signal handler" );
     96 	}
     97 
     98 	if ( called == 1 )
     99 	{
    100 
    101 		/* Raise the signal again. It should be masked */
    102 		ret = raise( SIGNAL );
    103 
    104 		if ( ret != 0 )
    105 		{
    106 			UNRESOLVED( ret, "Failed to raise %%MYSIG%% again" );
    107 		}
    108 
    109 		/* check the signal is pending */
    110 		ret = sigpending( &pending );
    111 
    112 		if ( ret != 0 )
    113 		{
    114 			UNRESOLVED( ret, "Failed to get pending signal set" );
    115 		}
    116 
    117 		ret = sigismember( &pending, SIGNAL );
    118 
    119 		if ( ret != 1 )
    120 		{
    121 			FAILED( "signal is not pending" );
    122 		}
    123 	}
    124 
    125 	called++;
    126 }
    127 
    128 /* main function */
    129 int main()
    130 {
    131 	int ret;
    132 
    133 	struct sigaction sa;
    134 
    135 	/* Initialize output */
    136 	output_init();
    137 
    138 	/* Set the signal handler */
    139 	sa.sa_flags = 0;
    140 
    141 	sa.sa_handler = handler;
    142 
    143 	ret = sigemptyset( &sa.sa_mask );
    144 
    145 	if ( ret != 0 )
    146 	{
    147 		UNRESOLVED( ret, "Failed to empty signal set" );
    148 	}
    149 
    150 	/* Install the signal handler for %%MYSIG%% */
    151 	ret = sigaction( SIGNAL, &sa, 0 );
    152 
    153 	if ( ret != 0 )
    154 	{
    155 		UNRESOLVED( ret, "Failed to set signal handler" );
    156 	}
    157 
    158 	ret = raise( SIGNAL );
    159 
    160 	if ( ret != 0 )
    161 	{
    162 		UNRESOLVED( ret, "Failed to raise %%MYSIG%%" );
    163 	}
    164 
    165 	while ( called != 4 )
    166 		sched_yield();
    167 
    168 	/* Test passed */
    169 #if VERBOSE > 0
    170 
    171 	output( "Test passed\n" );
    172 
    173 #endif
    174 
    175 	PASSED;
    176 }
    177