1 //==========================================================================
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
44 // Contributors: nickg
46 // Description: Tests POSIX signal functionality.
48 //####DESCRIPTIONEND####
49 //==========================================================================
51 #include <cyg/infra/testcase.h>
52 #include <pkgconf/posix.h>
54 #if !defined(CYGPKG_POSIX_SIGNALS)
55 #define NA_MSG "POSIX signals not enabled"
56 #elif !defined(CYGPKG_POSIX_PTHREAD)
57 #define NA_MSG "POSIX threads not enabled"
69 #include <sys/types.h>
72 #include <semaphore.h>
75 //--------------------------------------------------------------------------
78 char thread_stack[PTHREAD_STACK_MIN*2];
80 //--------------------------------------------------------------------------
89 volatile int sigusr2_called = 0;
90 volatile int sigalrm_called = 0;
92 //--------------------------------------------------------------------------
93 // Signal handler functions
95 static void sigusr2( int signo )
97 CYG_TEST_INFO( "sigusr2() handler called" );
98 CYG_TEST_CHECK( signo == SIGUSR2, "Signal not SIGUSR2");
99 CYG_TEST_CHECK( pthread_equal(pthread_self(), thread1), "Not called in thread1");
104 static void sigalrm( int signo )
106 CYG_TEST_INFO( "sigalrm() handler called" );
107 CYG_TEST_CHECK( signo == SIGALRM, "Signal not SIGALRM");
108 CYG_TEST_CHECK( pthread_equal(pthread_self(), thread1), "Not called in thread1");
113 //--------------------------------------------------------------------------
115 void *pthread_entry1( void *arg)
119 struct timespec timeout;
122 CYG_TEST_INFO( "Thread 1 running" );
124 // Should have inherited parent's signal mask
125 pthread_sigmask( 0, NULL, &mask );
126 CYG_TEST_CHECK( sigismember( &mask, SIGALRM),
127 "SIGALRM mask inherited");
128 CYG_TEST_CHECK( sigismember( &mask, SIGUSR1),
129 "SIGUSR1 mask inherited");
130 CYG_TEST_CHECK( sigismember( &mask, SIGUSR2),
131 "SIGUSR2 mask inherited");
132 CYG_TEST_CHECK( sigismember( &mask, SIGSEGV),
133 "SIGSEGV mask inherited");
138 // remove USR2 and ALRM signals
139 sigdelset( &mask, SIGUSR2 );
140 sigdelset( &mask, SIGALRM );
143 pthread_sigmask( SIG_SETMASK, &mask, NULL );
145 // Get main thread going again
152 CYG_TEST_INFO( "Thread1: calling sigtimedwait()");
154 // Wait for a signal to be delivered
155 sig = sigtimedwait( &mask, &info, &timeout );
157 sig2 = info.si_signo;
159 CYG_TEST_CHECK( sig == sig2, "sigtimedwait return value not equal");
160 CYG_TEST_CHECK( sig == SIGUSR1, "Signal not delivered");
162 while( sigusr2_called != 2 )
164 CYG_TEST_INFO( "Thread1: calling pause()");
168 errno = 0; // strictly correct to reset errno first
170 // now wait for SIGALRM to be delivered
171 CYG_TEST_INFO( "Thread1: calling pause()");
173 CYG_TEST_CHECK( -1==err, "pause returned -1");
174 CYG_TEST_CHECK( EINTR==errno, "errno set to EINTR");
176 // generate another SIGALRM and wait for it to be delivered too
177 // we need to mask it first though
183 pthread_sigmask( SIG_SETMASK, &mask, NULL );
186 CYG_TEST_INFO( "Thread1: calling sigwait()");
187 err = sigwait( &mask, &sig);
188 CYG_TEST_CHECK( 0==err, "sigwait returned -1");
189 CYG_TEST_CHECK( sig==SIGALRM, "sigwait caught alarm");
191 CYG_TEST_INFO( "Thread1: calling pthread_exit()");
192 pthread_exit( (void *)((int)arg+sig2) );
195 //--------------------------------------------------------------------------
197 int main(int argc, char **argv)
207 // Make a full signal set
211 // Install signal handlers
215 sa.sa_handler = sigusr2;
219 ret = sigaction( SIGUSR2, &sa, NULL );
221 CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
227 sa.sa_handler = sigalrm;
231 ret = sigaction( SIGALRM, &sa, NULL );
233 CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
238 pthread_sigmask( SIG_SETMASK, &mask, NULL );
240 sem_init( &sem, 0, 0 );
242 // Create test thread
243 pthread_attr_init( &attr );
245 pthread_attr_setstackaddr( &attr, (void *)&thread_stack[sizeof(thread_stack)] );
246 pthread_attr_setstacksize( &attr, sizeof(thread_stack) );
248 pthread_create( &thread1,
253 // Wait for other thread to get started
254 CYG_TEST_INFO( "Main: calling sem_wait()");
259 // send a signal to the other thread
260 CYG_TEST_INFO( "Main: calling sigqueue(SIGUSR1)");
261 sigqueue( 0, SIGUSR1, value );
263 // Send the signal via kill
264 CYG_TEST_INFO( "Main: calling kill(0, SIGUSR2)");
267 // Wait for thread1 to call pause()
268 CYG_TEST_INFO( "Main: calling sleep(1)");
272 CYG_TEST_INFO( "Main: calling kill(0, SIGUSR2)");
275 // Set up an alarm for 1 second hence
276 CYG_TEST_INFO( "Main: calling alarm(1)");
279 // Wait for alarm signal to be delivered to thread1
280 CYG_TEST_INFO( "Main: calling sleep(2)");
283 // Now join with thread1
284 CYG_TEST_INFO( "Main: calling pthread_join()");
285 pthread_join( thread1, &retval );
287 CYG_TEST_CHECK( sigusr2_called == 2, "SIGUSR2 signal handler not called twice" );
289 CYG_TEST_CHECK( sigalrm_called == 1, "SIGALRM signal handler not called" );
293 if( (long)retval == 0x12345678+SIGUSR1 )
294 CYG_TEST_PASS_FINISH( "signal1" );
296 CYG_TEST_FAIL_FINISH( "signal1" );
301 //--------------------------------------------------------------------------