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