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 SIGBUS 24* -> raise SIGBUS 25* -> In handler, check for reentrance then raise SIGBUS 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 SIGBUS 78 79/******************************************************************************/ 80/*************************** Test case ***********************************/ 81/******************************************************************************/ 82 83int called = 0; 84 85void 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 SIGBUS 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 */ 122int 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 SIGBUS */ 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 SIGBUS"); 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