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