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