1/*
2* Copyright (c) 2003, Intel Corporation. All rights reserved.
3* Created by:  salwan.searty REMOVE-THIS AT intel DOT com
4* This file is licensed under the GPL license.  For the full content
5* of this license, see the COPYING file at the top level of this
6* source tree.
7
8The resulting set shall be the the signal set pointed to by set
9
10Steps:
111. Have main create a new thread and wait for its termination.
122. Inside the new thread, set up the signal mask such that it contains
13 only SIGABRT (by passing SIG_SETMASK value to pthread_sigmask)
144. Raise SIGABRT, and make sure that the handler associated with it
15 wasn't executed, otherwise fail.
165. Also make sure that SIGABRT is pending, otherwise fail.
17
18* patch *
195b. Change mask to SIGUSR1 and check that the handler is called. This means
20that SIG_SETMASK removed the old signal from the set.
21* /patch *
22
236. Pass one of three return codes to the main() function:
24 - A value of -1 if SIGABRT wasn't found pending or
25   causes the handler to be executed.
26 - A value of 0 if SIGABRT was in fact pending and the handler
27   wasn't executed.
28 - A value of 1 incase of any UNRESOLVED situation such as an
29   unexpected function failure.
30*/
31
32#include <pthread.h>
33#include <signal.h>
34#include <stdio.h>
35#include "posixtest.h"
36
37int handler_called = 0;
38
39void handler( int signo )
40{
41	handler_called = 1;
42}
43
44void *a_thread_func()
45{
46
47	struct sigaction act;
48	sigset_t blocked_set, pending_set;
49	sigemptyset( &blocked_set );
50	sigaddset( &blocked_set, SIGABRT );
51
52	act.sa_handler = handler;
53	act.sa_flags = 0;
54	sigemptyset( &act.sa_mask );
55
56	if ( sigaction( SIGABRT, &act, 0 ) == -1 )
57	{
58		perror( "Unexpected error while attempting to setup test "
59		        "pre-conditions" );
60		pthread_exit( ( void* ) 1 );
61	}
62
63	if ( pthread_sigmask( SIG_SETMASK, &blocked_set, NULL ) == -1 )
64	{
65		perror( "Unexpected error while attempting to use pthread_sigmask.\n" );
66		pthread_exit( ( void* ) 1 );
67	}
68
69	if ( raise( SIGABRT ) == -1 )
70	{
71		perror( "Unexpected error while attempting to setup test "
72		        "pre-conditions" );
73		pthread_exit( ( void* ) 1 );
74	}
75
76	if ( handler_called )
77	{
78		printf( "FAIL: Signal was not blocked\n" );
79		pthread_exit( ( void* ) - 1 );
80	}
81
82	if ( sigpending( &pending_set ) == -1 )
83	{
84		perror( "Unexpected error while attempting to use sigpending\n" );
85		pthread_exit( ( void* ) 1 );
86	}
87
88	if ( sigismember( &pending_set, SIGABRT ) == -1 )
89	{
90		perror( "Unexpected error while attempting to use sigismember.\n" );
91		pthread_exit( ( void* ) - 1 );
92	}
93
94	if ( sigismember( &pending_set, SIGABRT ) != 1 )
95	{
96		perror( "FAIL: sigismember did not return 1\n" );
97		pthread_exit( ( void* ) 1 );
98	}
99
100	sigemptyset( &blocked_set );
101	sigaddset( &blocked_set, SIGUSR1 );
102
103	if ( pthread_sigmask( SIG_SETMASK, &blocked_set, NULL ) == -1 )
104	{
105		perror( "Unexpected error while attempting to use pthread_sigmask.\n" );
106		pthread_exit( ( void* ) 1 );
107	}
108
109	sched_yield();
110
111	if ( !handler_called )
112	{
113		printf( "FAIL: Old signal was not removed from mask.\n" );
114		pthread_exit( ( void* ) - 1 );
115	}
116
117	pthread_exit( ( void* ) 0 );
118	return NULL;
119
120}
121
122int main()
123{
124
125	int * thread_return_value;
126
127	pthread_t new_thread;
128
129	if ( pthread_create( &new_thread, NULL, a_thread_func, NULL ) != 0 )
130	{
131		perror( "Error creating new thread\n" );
132		return PTS_UNRESOLVED;
133	}
134
135	if ( pthread_join( new_thread, ( void* ) & thread_return_value ) != 0 )
136	{
137		perror( "Error in pthread_join()\n" );
138		return PTS_UNRESOLVED;
139	}
140
141	if ( ( long ) thread_return_value != 0 )
142	{
143		if ( ( long ) thread_return_value == 1 )
144		{
145			printf ( "Test UNRESOLVED\n" );
146			return PTS_UNRESOLVED;
147		}
148		else if ( ( long ) thread_return_value == -1 )
149		{
150			printf ( "Test FAILED\n" );
151			return PTS_FAIL;
152		}
153		else
154		{
155			printf ( "Test UNRESOLVED\n" );
156			return PTS_UNRESOLVED;
157		}
158	}
159
160	printf( "Test PASSED\n" );
161	return PTS_PASS;
162}
163
164