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