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