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