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 * This sample test aims to check the following assertions: 18 * 19 * If SA_NODEFER is not set in sa_flags, the caught signal is added to the 20 * thread's signal mask during the handler execution. 21 22 * The steps are: 23 * -> register a signal handler for SIGINT 24 * -> raise SIGINT 25 * -> In handler, check for reentrance then raise SIGINT again. 26 27 * The test fails if signal handler if reentered or signal is not pending when raised again. 28 */ 29 30 /* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ 31 #define _POSIX_C_SOURCE 200112L 32 33 /******************************************************************************/ 34 /*************************** standard includes ********************************/ 35 /******************************************************************************/ 36 #include <pthread.h> 37 #include <stdarg.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <unistd.h> 42 43 #include <signal.h> 44 #include <errno.h> 45 46 /******************************************************************************/ 47 /*************************** Test framework *******************************/ 48 /******************************************************************************/ 49 #include "../testfrmw/testfrmw.h" 50 #include "../testfrmw/testfrmw.c" 51 /* This header is responsible for defining the following macros: 52 * UNRESOLVED(ret, descr); 53 * where descr is a description of the error and ret is an int 54 * (error code for example) 55 * FAILED(descr); 56 * where descr is a short text saying why the test has failed. 57 * PASSED(); 58 * No parameter. 59 * 60 * Both three macros shall terminate the calling process. 61 * The testcase shall not terminate in any other maneer. 62 * 63 * The other file defines the functions 64 * void output_init() 65 * void output(char * string, ...) 66 * 67 * Those may be used to output information. 68 */ 69 70 /******************************************************************************/ 71 /**************************** Configuration ***********************************/ 72 /******************************************************************************/ 73 #ifndef VERBOSE 74 #define VERBOSE 1 75 #endif 76 77 #define SIGNAL SIGINT 78 79 /******************************************************************************/ 80 /*************************** Test case ***********************************/ 81 /******************************************************************************/ 82 83 int called = 0; 84 85 void handler(int sig) 86 { 87 int ret; 88 sigset_t pending; 89 called++; 90 91 if (called == 2) { 92 FAILED("Signal was not masked in signal handler"); 93 } 94 95 if (called == 1) { 96 97 /* Raise the signal again. It should be masked */ 98 ret = raise(SIGNAL); 99 100 if (ret != 0) { 101 UNRESOLVED(ret, "Failed to raise SIGINT again"); 102 } 103 104 /* check the signal is pending */ 105 ret = sigpending(&pending); 106 107 if (ret != 0) { 108 UNRESOLVED(ret, "Failed to get pending signal set"); 109 } 110 111 ret = sigismember(&pending, SIGNAL); 112 113 if (ret != 1) { 114 FAILED("signal is not pending"); 115 } 116 } 117 118 called++; 119 } 120 121 /* main function */ 122 int main(void) 123 { 124 int ret; 125 126 struct sigaction sa; 127 128 /* Initialize output */ 129 output_init(); 130 131 /* Set the signal handler */ 132 sa.sa_flags = 0; 133 134 sa.sa_handler = handler; 135 136 ret = sigemptyset(&sa.sa_mask); 137 138 if (ret != 0) { 139 UNRESOLVED(ret, "Failed to empty signal set"); 140 } 141 142 /* Install the signal handler for SIGINT */ 143 ret = sigaction(SIGNAL, &sa, 0); 144 145 if (ret != 0) { 146 UNRESOLVED(ret, "Failed to set signal handler"); 147 } 148 149 ret = raise(SIGNAL); 150 151 if (ret != 0) { 152 UNRESOLVED(ret, "Failed to raise SIGINT"); 153 } 154 155 while (called != 4) 156 sched_yield(); 157 158 /* Test passed */ 159 #if VERBOSE > 0 160 161 output("Test passed\n"); 162 163 #endif 164 165 PASSED; 166 } 167