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., 59 15* Temple Place - Suite 330, Boston MA 02111-1307, USA. 16 17 18* This sample test aims to check the following assertions: 19* 20* If the signal action was set with the signal() function, getting it into oact 21then reinstalling it with act must be valid. 22 23* The steps are: 24* -> register a signal handler for SIGURG with signal(). 25* -> check this signal handler works. 26* -> change the signal handler with sigaction, saving old handler in oact. 27* -> check the new signal handler works. 28* -> set the old signal handler back 29* -> check the old signal handler still works. 30 31* The test fails if a signal handler does not work as expected. 32*/ 33 34 35/* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ 36#define _POSIX_C_SOURCE 200112L 37 38/******************************************************************************/ 39/*************************** standard includes ********************************/ 40/******************************************************************************/ 41#include <stdarg.h> 42#include <stdio.h> 43#include <stdlib.h> 44#include <string.h> 45#include <unistd.h> 46 47#include <signal.h> 48#include <errno.h> 49 50/******************************************************************************/ 51/*************************** Test framework *******************************/ 52/******************************************************************************/ 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#include "posixtest.h" 72#include <time.h> 73#include <sys/types.h> 74 75#ifdef __GNUC__ /* We are using GCC */ 76 77#define UNRESOLVED(x, s) \ 78 { output("Test %s unresolved: got %i (%s) on line %i (%s)\n", __FILE__, x, strerror(x), __LINE__, s); \ 79 output_fini(); \ 80 exit(PTS_UNRESOLVED); } 81 82#define FAILED(s) \ 83 { output("Test %s FAILED: %s\n", __FILE__, s); \ 84 output_fini(); \ 85 exit(PTS_FAIL); } 86 87#define PASSED \ 88 output_fini(); \ 89 exit(PTS_PASS); 90 91#define UNTESTED(s) \ 92{ output("File %s cannot test: %s\n", __FILE__, s); \ 93 output_fini(); \ 94 exit(PTS_UNTESTED); \ 95} 96 97#else /* not using GCC */ 98 99#define UNRESOLVED(x, s) \ 100 { output("Test unresolved: got %i (%s) on line %i (%s)\n", x, strerror(x), __LINE__, s); \ 101 output_fini(); \ 102 exit(PTS_UNRESOLVED); } 103 104#define FAILED(s) \ 105 { output("Test FAILED: %s\n", s); \ 106 output_fini(); \ 107 exit(PTS_FAIL); } 108 109#define PASSED \ 110 output_fini(); \ 111 exit(PTS_PASS); 112 113#define UNTESTED(s) \ 114{ output("Unable to test: %s\n", s); \ 115 output_fini(); \ 116 exit(PTS_UNTESTED); \ 117} 118 119#endif 120void output_init() 121{ 122 /* do nothing */ 123 return ; 124} 125 126void output( char * string, ... ) 127{ 128 va_list ap; 129#ifndef PLOT_OUTPUT 130 char *ts = "[??:??:??]"; 131 132 struct tm * now; 133 time_t nw; 134#endif 135 136#ifndef PLOT_OUTPUT 137 nw = time( NULL ); 138 now = localtime( &nw ); 139 140 if ( now == NULL ) 141 printf( ts ); 142 else 143 printf( "[%2.2d:%2.2d:%2.2d]", now->tm_hour, now->tm_min, now->tm_sec ); 144 145#endif 146 va_start( ap, string ); 147 148 vprintf( string, ap ); 149 150 va_end( ap ); 151 152} 153 154void output_fini() 155{ 156 /*do nothing */ 157 return ; 158} 159 160/******************************************************************************/ 161/**************************** Configuration ***********************************/ 162/******************************************************************************/ 163#ifndef VERBOSE 164#define VERBOSE 1 165#endif 166 167#define SIGNAL SIGURG 168 169/******************************************************************************/ 170/*************************** Test case ***********************************/ 171/******************************************************************************/ 172 173sig_atomic_t called = 1; 174 175void handler_1( int sig ) 176{ 177 called++; 178} 179 180void handler_2( int sig ) 181{ 182 called--; 183} 184 185/* main function */ 186int main() 187{ 188 int ret; 189 190 struct sigaction sa, save; 191 192 /* Initialize output */ 193 output_init(); 194 195 /* Register the signal handler with signal */ 196 197 if ( SIG_ERR == signal( SIGNAL, handler_1 ) ) 198 { 199 UNRESOLVED( errno, "Failed to register signal handler with signal()" ); 200 } 201 202 /* As whether signal handler is restored to default when executed 203 is implementation defined, we cannot check it was registered here. */ 204 205 /* Set the new signal handler with sigaction*/ 206 sa.sa_flags = 0; 207 208 sa.sa_handler = handler_2; 209 210 ret = sigemptyset( &sa.sa_mask ); 211 212 if ( ret != 0 ) 213 { 214 UNRESOLVED( ret, "Failed to empty signal set" ); 215 } 216 217 /* Install the signal handler for SIGURG */ 218 ret = sigaction( SIGNAL, &sa, &save ); 219 220 if ( ret != 0 ) 221 { 222 UNRESOLVED( ret, "Failed to set signal handler" ); 223 } 224 225 /* Check the signal handler has been set up */ 226 ret = raise( SIGNAL ); 227 228 if ( ret != 0 ) 229 { 230 UNRESOLVED( ret , "Failed to raise the signal" ); 231 } 232 233 if ( called != 0 ) 234 { 235 FAILED( "handler not executed" ); 236 } 237 238 /* Restore the first signal handler */ 239 ret = sigaction( SIGNAL, &save, 0 ); 240 241 if ( ret != 0 ) 242 { 243 UNRESOLVED( ret, "Failed to set signal handler" ); 244 } 245 246 /* Check the signal handler has been set up */ 247 ret = raise( SIGNAL ); 248 249 if ( ret != 0 ) 250 { 251 UNRESOLVED( ret , "Failed to raise the signal" ); 252 } 253 254 if ( called != 1 ) 255 { 256 FAILED( "handler not executed" ); 257 } 258 259 260 /* Test passed */ 261#if VERBOSE > 0 262 263 output( "Test passed\n" ); 264 265#endif 266 267 PASSED; 268} 269