• 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 
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