• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
90 sig_atomic_t latest = 0;
91 
handler(int sig,siginfo_t * info,void * context)92 void 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 */
main(void)108 int 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