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 SA_SIGINFO is set and realtime signals extension is supported, queueable 21* signals generated by sigqueue or some other functions are delivered in FIFO 22* order. 23 24* The steps are: 25* -> Test for RTS extension support 26* -> install a handler for SIGRTMAX signal with SA_SIGINFO set. 27* -> Mask this signal 28* -> Generate the signal several imes with sigqueue and known user values. 29* -> unmask the signal 30* -> check that the signals are delivered in order. 31 32* The test fails if the signals are not delivered in FIFO order. 33*/ 34 35/* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ 36#define _POSIX_C_SOURCE 200112L 37 38/* This test uses some XSI features */ 39//#define _XOPEN_SOURCE 600 40 41/******************************************************************************/ 42/*************************** standard includes ********************************/ 43/******************************************************************************/ 44#include <pthread.h> 45#include <stdarg.h> 46#include <stdio.h> 47#include <stdlib.h> 48#include <string.h> 49#include <unistd.h> 50 51#include <signal.h> 52#include <errno.h> 53 54/******************************************************************************/ 55/*************************** Test framework *******************************/ 56/******************************************************************************/ 57#include "testfrmw.h" 58#include "testfrmw.c" 59/* This header is responsible for defining the following macros: 60 * UNRESOLVED(ret, descr); 61 * where descr is a description of the error and ret is an int 62 * (error code for example) 63 * FAILED(descr); 64 * where descr is a short text saying why the test has failed. 65 * PASSED(); 66 * No parameter. 67 * 68 * Both three macros shall terminate the calling process. 69 * The testcase shall not terminate in any other maneer. 70 * 71 * The other file defines the functions 72 * void output_init() 73 * void output(char * string, ...) 74 * 75 * Those may be used to output information. 76 */ 77 78/******************************************************************************/ 79/**************************** Configuration ***********************************/ 80/******************************************************************************/ 81#ifndef VERBOSE 82#define VERBOSE 1 83#endif 84 85#define QUEUELENGTH 10 86 87/******************************************************************************/ 88/*************************** Test case ***********************************/ 89/******************************************************************************/ 90 91sig_atomic_t latest = 0; 92 93void handler( int sig, siginfo_t *info, void *context ) 94{ 95 if ( info->si_signo != SIGRTMAX ) 96 { 97 output( "Received unexpected signal %d\n", info->si_signo ); 98 } 99 else 100 { 101 latest++; 102 103 if ( latest != info->si_value.sival_int ) 104 { 105 output( "Got signal %d, expected %d!\n", info->si_value.sival_int, latest ); 106 FAILED( "Wrong signal delivered -- no FIFO order?" ); 107 } 108 } 109} 110 111/* main function */ 112int main() 113{ 114 int ret; 115 long rts; 116 117 struct sigaction sa; 118 union sigval sv; 119 sigset_t mask; 120 121 /* Initialize output */ 122 output_init(); 123 124 /* Test the RTS extension */ 125 rts = sysconf( _SC_REALTIME_SIGNALS ); 126 127 if ( rts < 0L ) 128 { 129 UNTESTED( "This test needs the RTS extension" ); 130 } 131 132 /* Set the signal handler */ 133 sa.sa_flags = SA_SIGINFO; 134 135 sa.sa_sigaction = handler; 136 137 ret = sigemptyset( &sa.sa_mask ); 138 139 if ( ret != 0 ) 140 { 141 UNRESOLVED( ret, "Failed to empty signal set" ); 142 } 143 144 /* Install the signal handler for SIGRTMAX */ 145 ret = sigaction( SIGRTMAX, &sa, 0 ); 146 147 if ( ret != 0 ) 148 { 149 UNRESOLVED( ret, "Failed to set signal handler" ); 150 } 151 152 /* Mask this signal */ 153 ret = sigemptyset( &mask ); 154 155 if ( ret != 0 ) 156 { 157 UNRESOLVED( ret, "An error occured while initializing mask" ); 158 } 159 160 ret = sigaddset( &mask, SIGRTMAX ); 161 162 if ( ret != 0 ) 163 { 164 UNRESOLVED( ret, "Failed to add SIGRTMAX to signal set" ); 165 } 166 167 ret = sigprocmask( SIG_BLOCK, &mask, NULL ); 168 169 if ( ret != 0 ) 170 { 171 UNRESOLVED( ret, "Failed to set process signal mask" ); 172 } 173 174 /* Now queue the signal to be pending */ 175 176 for ( sv.sival_int = 1; sv.sival_int <= QUEUELENGTH; sv.sival_int++ ) 177 { 178 ret = sigqueue( getpid(), SIGRTMAX, sv ); 179 180 if ( ret != 0 ) 181 { 182 UNRESOLVED( ret, "Failed to queue the signal" ); 183 } 184 } 185 186 if ( latest != 0 ) 187 { 188 FAILED( "Signal was delivered while masked??" ); 189 } 190 191 /* And finally unmask the signal so it is delivered */ 192 ret = sigprocmask( SIG_UNBLOCK, &mask, NULL ); 193 194 if ( ret != 0 ) 195 { 196 UNRESOLVED( ret, "Failed to set process signal mask" ); 197 } 198 199 sched_yield(); 200 201 /* Check the signal has been delivered as expected */ 202 203 if ( latest != QUEUELENGTH ) 204 { 205 output( "Only %d signal delivered instead of %d\n", latest, QUEUELENGTH ); 206 207 if ( latest == 1 ) 208 { 209 UNTESTED( "It seems like SIGRTMAX is not a queuable signal here?" ); 210 } 211 } 212 213 /* Test passed */ 214#if VERBOSE > 0 215 216 output( "Test passed\n" ); 217 218#endif 219 220 PASSED; 221} 222