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 #define _XOPEN_SOURCE 600
32
33 #include <pthread.h>
34 #include <stdio.h>
35 #include <signal.h>
36 #include <errno.h>
37 #include <unistd.h>
38 #include "posixtest.h"
39
40 #define SIGTOTEST SIGABRT
41 #define INMAIN 0
42 #define INTHREAD 1
43
44 static int handler_called;
45 static int return_value = 2;
46 static int sem = INMAIN;
47
handler()48 static void handler()
49 {
50 printf("signal was called\n");
51 handler_called = 1;
52 return;
53 }
54
a_thread_func()55 static void *a_thread_func()
56 {
57 struct sigaction act;
58 sigset_t pendingset;
59
60 act.sa_flags = 0;
61 act.sa_handler = handler;
62 sigemptyset(&act.sa_mask);
63 sigaction(SIGTOTEST, &act, 0);
64 sighold(SIGTOTEST);
65
66 if ((sigpause(SIGTOTEST) != -1) || (errno != EINTR)) {
67 printf("Test UNRESOLVED: sigpause didn't return -1 "
68 "and/or didn't set errno correctly.");
69 return_value = 2;
70 return NULL;
71 }
72
73 sleep(1);
74
75 raise(SIGTOTEST);
76 sigpending(&pendingset);
77 if (sigismember(&pendingset, SIGTOTEST) == 1) {
78 printf("Test PASSED: signal mask was restored when "
79 "sigpause returned.");
80 return_value = 0;
81 }
82
83 sem = INMAIN;
84 return NULL;
85 }
86
main(void)87 int main(void)
88 {
89 pthread_t new_th;
90
91 if (pthread_create(&new_th, NULL, a_thread_func, NULL) != 0) {
92 perror("Error creating thread\n");
93 return PTS_UNRESOLVED;
94 }
95
96 sleep(1);
97
98 if (pthread_kill(new_th, SIGTOTEST) != 0) {
99 printf("Test UNRESOLVED: Couldn't send signal to thread\n");
100 return PTS_UNRESOLVED;
101 }
102
103 sem = INTHREAD;
104 while (sem == INTHREAD)
105 sleep(1);
106
107 if (handler_called != 1) {
108 printf("Test UNRESOLVED: signal wasn't removed from "
109 "signal mask\n");
110 return PTS_UNRESOLVED;
111 }
112
113 if (return_value != 0) {
114 if (return_value == 1)
115 return PTS_FAIL;
116 if (return_value == 2)
117 return PTS_UNRESOLVED;
118 return PTS_UNRESOLVED;
119 }
120
121 printf("Test PASSED\n");
122 return PTS_PASS;
123 }
124