1 /*
2 * Copyright (c) 2004, 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 assertion:
19 *
20 * The function does not return EINTR
21
22 * The steps are:
23 * -> kill a thread which calls pthread_kill
24 * -> check that EINTR is never returned
25
26 */
27
28
29 /* We are testing conformance to IEEE Std 1003.1, 2003 Edition */
30 #define _POSIX_C_SOURCE 200112L
31
32 /********************************************************************************************/
33 /****************************** standard includes *****************************************/
34 /********************************************************************************************/
35 #include <pthread.h>
36 #include <stdarg.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41
42 #include <semaphore.h>
43 #include <errno.h>
44 #include <signal.h>
45
46 /********************************************************************************************/
47 /****************************** Test framework *****************************************/
48 /********************************************************************************************/
49 #include "testfrmw.h"
50 #include "testfrmw.c"
51 /* This header is responsible for defining the following macros:
52 * UNRESOLVED(ret, descr);
53 * where descr is a description of the error and ret is an int (error code for example)
54 * FAILED(descr);
55 * where descr is a short text saying why the test has failed.
56 * PASSED();
57 * No parameter.
58 *
59 * Both three macros shall terminate the calling process.
60 * The testcase shall not terminate in any other maneer.
61 *
62 * The other file defines the functions
63 * void output_init()
64 * void output(char * string, ...)
65 *
66 * Those may be used to output information.
67 */
68
69 /********************************************************************************************/
70 /********************************** Configuration ******************************************/
71 /********************************************************************************************/
72 #ifndef VERBOSE
73 #define VERBOSE 1
74 #endif
75
76 #define WITH_SYNCHRO
77
78
79 /********************************************************************************************/
80 /*********************************** Test cases *****************************************/
81 /********************************************************************************************/
82
83 char do_it = 1;
84 unsigned long count_ope = 0;
85 #ifdef WITH_SYNCHRO
86 sem_t semsig1;
87 sem_t semsig2;
88 unsigned long count_sig = 0;
89 #endif
90
91 sigset_t usersigs;
92
93 typedef struct
94 {
95 int sig;
96 #ifdef WITH_SYNCHRO
97 sem_t *sem;
98 #endif
99 }
100
101 thestruct;
102
103 /* the following function keeps on sending the signal to the process */
sendsig(void * arg)104 void * sendsig ( void * arg )
105 {
106 thestruct * thearg = ( thestruct * ) arg;
107 int ret;
108 pid_t process;
109
110 process = getpid();
111
112 /* We block the signals SIGUSR1 and SIGUSR2 for this THREAD */
113 ret = pthread_sigmask( SIG_BLOCK, &usersigs, NULL );
114
115 if ( ret != 0 )
116 {
117 UNRESOLVED( ret, "Unable to block SIGUSR1 and SIGUSR2 in signal thread" );
118 }
119
120 while ( do_it )
121 {
122 #ifdef WITH_SYNCHRO
123
124 if ( ( ret = sem_wait( thearg->sem ) ) )
125 {
126 UNRESOLVED( errno, "Sem_wait in sendsig" );
127 }
128
129 count_sig++;
130 #endif
131
132 ret = kill( process, thearg->sig );
133
134 if ( ret != 0 )
135 {
136 UNRESOLVED( errno, "Kill in sendsig" );
137 }
138
139 }
140
141 return NULL;
142 }
143
144 /* Next are the signal handlers. */
145 /* This one is registered for signal SIGUSR1 */
sighdl1(int sig)146 void sighdl1( int sig )
147 {
148 #ifdef WITH_SYNCHRO
149
150 if ( sem_post( &semsig1 ) )
151 {
152 UNRESOLVED( errno, "Sem_post in signal handler 1" );
153 }
154
155 #endif
156 }
157
158 /* This one is registered for signal SIGUSR2 */
sighdl2(int sig)159 void sighdl2( int sig )
160 {
161 #ifdef WITH_SYNCHRO
162
163 if ( sem_post( &semsig2 ) )
164 {
165 UNRESOLVED( errno, "Sem_post in signal handler 2" );
166 }
167
168 #endif
169 }
170
171 int init_ctl;
172 /* Init function */
initializer(void)173 void initializer( void )
174 {
175 init_ctl++;
176 return ;
177 }
178
179
180 /* Test function -- calls pthread_kill() and checks that EINTR is never returned. */
test(void * arg)181 void * test( void * arg )
182 {
183 int ret = 0;
184
185 /* We don't block the signals SIGUSR1 and SIGUSR2 for this THREAD */
186 ret = pthread_sigmask( SIG_UNBLOCK, &usersigs, NULL );
187
188 if ( ret != 0 )
189 {
190 UNRESOLVED( ret, "Unable to unblock SIGUSR1 and SIGUSR2 in worker thread" );
191 }
192
193
194 while ( do_it )
195 {
196 count_ope++;
197
198 ret = pthread_kill( pthread_self(), 0 );
199
200 if ( ret == EINTR )
201 {
202 FAILED( "pthread_kill returned EINTR" );
203 }
204
205 if ( ret != 0 )
206 {
207 UNRESOLVED( ret, "pthread_kill returned an unexpected error" );
208 }
209
210 ret = pthread_kill( pthread_self(), SIGUSR1 );
211
212 if ( ret == EINTR )
213 {
214 FAILED( "pthread_kill returned EINTR" );
215 }
216
217 if ( ret != 0 )
218 {
219 UNRESOLVED( ret, "pthread_kill returned an unexpected error" );
220 }
221 }
222
223 return NULL;
224 }
225
226 /* Main function */
main(int argc,char * argv[])227 int main ( int argc, char * argv[] )
228 {
229 int ret;
230 pthread_t th_work, th_sig1, th_sig2;
231 thestruct arg1, arg2;
232
233 struct sigaction sa;
234
235 /* Initialize output routine */
236 output_init();
237
238 /* We need to register the signal handlers for the PROCESS */
239 sigemptyset ( &sa.sa_mask );
240 sa.sa_flags = 0;
241 sa.sa_handler = sighdl1;
242
243 if ( ( ret = sigaction ( SIGUSR1, &sa, NULL ) ) )
244 {
245 UNRESOLVED( ret, "Unable to register signal handler1" );
246 }
247
248 sa.sa_handler = sighdl2;
249
250 if ( ( ret = sigaction ( SIGUSR2, &sa, NULL ) ) )
251 {
252 UNRESOLVED( ret, "Unable to register signal handler2" );
253 }
254
255 /* We prepare a signal set which includes SIGUSR1 and SIGUSR2 */
256 sigemptyset( &usersigs );
257
258 ret = sigaddset( &usersigs, SIGUSR1 );
259
260 ret |= sigaddset( &usersigs, SIGUSR2 );
261
262 if ( ret != 0 )
263 {
264 UNRESOLVED( ret, "Unable to add SIGUSR1 or 2 to a signal set" );
265 }
266
267 /* We now block the signals SIGUSR1 and SIGUSR2 for this THREAD */
268 ret = pthread_sigmask( SIG_BLOCK, &usersigs, NULL );
269
270 if ( ret != 0 )
271 {
272 UNRESOLVED( ret, "Unable to block SIGUSR1 and SIGUSR2 in main thread" );
273 }
274
275 #ifdef WITH_SYNCHRO
276 if ( sem_init( &semsig1, 0, 1 ) )
277 {
278 UNRESOLVED( errno, "Semsig1 init" );
279 }
280
281 if ( sem_init( &semsig2, 0, 1 ) )
282 {
283 UNRESOLVED( errno, "Semsig2 init" );
284 }
285
286 #endif
287
288 if ( ( ret = pthread_create( &th_work, NULL, test, NULL ) ) )
289 {
290 UNRESOLVED( ret, "Worker thread creation failed" );
291 }
292
293 arg1.sig = SIGUSR1;
294 arg2.sig = SIGUSR2;
295 #ifdef WITH_SYNCHRO
296 arg1.sem = &semsig1;
297 arg2.sem = &semsig2;
298 #endif
299
300
301
302 if ( ( ret = pthread_create( &th_sig1, NULL, sendsig, ( void * ) & arg1 ) ) )
303 {
304 UNRESOLVED( ret, "Signal 1 sender thread creation failed" );
305 }
306
307 if ( ( ret = pthread_create( &th_sig2, NULL, sendsig, ( void * ) & arg2 ) ) )
308 {
309 UNRESOLVED( ret, "Signal 2 sender thread creation failed" );
310 }
311
312
313
314 /* Let's wait for a while now */
315 sleep( 1 );
316
317
318 /* Now stop the threads and join them */
319 do
320 {
321 do_it = 0;
322 }
323 while ( do_it );
324
325
326 if ( ( ret = pthread_join( th_sig1, NULL ) ) )
327 {
328 UNRESOLVED( ret, "Signal 1 sender thread join failed" );
329 }
330
331 if ( ( ret = pthread_join( th_sig2, NULL ) ) )
332 {
333 UNRESOLVED( ret, "Signal 2 sender thread join failed" );
334 }
335
336
337 if ( ( ret = pthread_join( th_work, NULL ) ) )
338 {
339 UNRESOLVED( ret, "Worker thread join failed" );
340 }
341
342
343 #if VERBOSE > 0
344 output( "Test executed successfully.\n" );
345
346 output( " %d operations.\n", count_ope );
347
348 #ifdef WITH_SYNCHRO
349 output( " %d signals were sent meanwhile.\n", count_sig );
350
351 #endif
352 #endif
353 PASSED;
354 }
355
356