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
8 This program verifies that sigpause() restores sig to the signal mask before
9 returning.
10
11 Steps:
12 1. From the main() function, create a new thread. Give the new thread a
13 a second to set up for receiving a signal, add SIGTOTEST to its signal
14 mask and to suspend itself using sigpause(SIGTOTEST).
15 2. Have main() send the signal indicated by SIGTOTEST to the new thread,
16 using pthread_kill(), and using the concept of semaphores, have the main()
17 3. Once the new thread returns from sigpause, have the new thread raise
18 SIGTOTEST. At this point, SIGTOTEST should be restored to the signal mask,
19 so the signal handler should not be called yet, and the signal should be
20 pending.
21 If it is not, set the variable return_value to 1, indicating a test failure.
22 4. Now, from the new thread, set sem back to INMAIN to allow main to continue
23 running.
24 5. The PTS exit code that main() will return with will depend on the value of
25 return_value:
26 PTS_UNRESOLVED if return value is 2
27 PTS_PASS if return value is 0
28 PTS_FAIL if return value is 1
29 */
30
31
32 #include <pthread.h>
33 #include <stdio.h>
34 #include <signal.h>
35 #include <errno.h>
36 #include <unistd.h>
37 #include "posixtest.h"
38
39 #define SIGTOTEST SIGABRT
40 #define INMAIN 0
41 #define INTHREAD 1
42
43 static int handler_called;
44 static int return_value = 2;
45 static int sem = INMAIN;
46
handler()47 static void handler()
48 {
49 printf("signal was called\n");
50 handler_called = 1;
51 return;
52 }
53
a_thread_func()54 static void *a_thread_func()
55 {
56 struct sigaction act;
57 sigset_t pendingset;
58
59 act.sa_flags = 0;
60 act.sa_handler = handler;
61 sigemptyset(&act.sa_mask);
62 sigaction(SIGTOTEST, &act, 0);
63 sighold(SIGTOTEST);
64
65 if ((sigpause(SIGTOTEST) != -1) || (errno != EINTR)) {
66 printf("Test UNRESOLVED: sigpause didn't return -1 "
67 "and/or didn't set errno correctly.");
68 return_value = 2;
69 return NULL;
70 }
71
72 sleep(1);
73
74 raise(SIGTOTEST);
75 sigpending(&pendingset);
76 if (sigismember(&pendingset, SIGTOTEST) == 1) {
77 printf("Test PASSED: signal mask was restored when "
78 "sigpause returned.");
79 return_value = 0;
80 }
81
82 sem = INMAIN;
83 return NULL;
84 }
85
main(void)86 int main(void)
87 {
88 pthread_t new_th;
89
90 if (pthread_create(&new_th, NULL, a_thread_func, NULL) != 0) {
91 perror("Error creating thread\n");
92 return PTS_UNRESOLVED;
93 }
94
95 sleep(1);
96
97 if (pthread_kill(new_th, SIGTOTEST) != 0) {
98 printf("Test UNRESOLVED: Couldn't send signal to thread\n");
99 return PTS_UNRESOLVED;
100 }
101
102 sem = INTHREAD;
103 while (sem == INTHREAD)
104 sleep(1);
105
106 if (handler_called != 1) {
107 printf("Test UNRESOLVED: signal wasn't removed from "
108 "signal mask\n");
109 return PTS_UNRESOLVED;
110 }
111
112 if (return_value != 0) {
113 if (return_value == 1)
114 return PTS_FAIL;
115 if (return_value == 2)
116 return PTS_UNRESOLVED;
117 return PTS_UNRESOLVED;
118 }
119
120 printf("Test PASSED\n");
121 return PTS_PASS;
122 }
123