1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <errno.h>
17 #include <signal.h>
18
19 #include "test.h"
20
21 static int handler_count = 0;
22 const int sig = SIGALRM;
23
handler(int sig)24 void handler(int sig)
25 {
26 handler_count++;
27 }
28
prepare(sigset_t * set)29 int prepare(sigset_t *set)
30 {
31 handler_count = 0;
32
33 struct sigaction act = {.sa_flags = 0, .sa_handler = handler};
34 struct sigaction old_act = {0};
35 int result = sigaction(sig, &act, &old_act);
36 if (result != 0) {
37 return result;
38 }
39
40 if (handler_count != 0) {
41 return -1;
42 }
43
44 result = raise(sig);
45 if (result != 0) {
46 return result;
47 }
48
49 if (handler_count != 1) {
50 return -1;
51 }
52
53 result = sigemptyset(set);
54 if (result != 0) {
55 return result;
56 }
57
58 result = sigaddset(set, sig);
59 if (result != 0) {
60 return result;
61 }
62
63 result = sigprocmask(SIG_BLOCK, NULL, set);
64 if (result != 0) {
65 return result;
66 }
67
68 return 0;
69 }
70
71 /**
72 * @tc.name : sigset_0100
73 * @tc.desc : modifies the disposition of the signal sig with a handler
74 * @tc.level : Level 0
75 */
sigset_0100(void)76 void sigset_0100(void)
77 {
78 sigset_t set;
79 int result = prepare(&set);
80 if (result != 0) {
81 t_error("%s failed: result = %d\n", __func__, result);
82 }
83
84 result = sigemptyset(&set);
85 if (result != 0) {
86 t_error("%s failed: result = %d\n", __func__, result);
87 }
88
89 errno = 0;
90 sigset(sig, handler);
91 if (errno != 0) {
92 t_error("%s failed: errno = %d\n", __func__, errno);
93 }
94
95 result = sigprocmask(SIG_BLOCK, NULL, &set);
96 if (result != 0) {
97 t_error("%s failed: result = %d\n", __func__, result);
98 }
99
100 result = sigismember(&set, sig);
101 if (result != 0) {
102 t_error("%s failed: result = %d\n", __func__, result);
103 }
104 }
105
106 /**
107 * @tc.name : sigset_0200
108 * @tc.desc : modifies the disposition of the signal sig with SIG_IGN
109 * @tc.level : Level 1
110 */
sigset_0200(void)111 void sigset_0200(void)
112 {
113 sigset_t set;
114 int result = prepare(&set);
115 if (result != 0) {
116 t_error("%s failed: result = %d\n", __func__, result);
117 }
118
119 result = sigemptyset(&set);
120 if (result != 0) {
121 t_error("%s failed: result = %d\n", __func__, result);
122 }
123
124 errno = 0;
125 sigset(sig, SIG_IGN);
126 if (errno != 0) {
127 t_error("%s failed: errno = %d\n", __func__, errno);
128 }
129
130 result = sigprocmask(SIG_BLOCK, NULL, &set);
131 if (result != 0) {
132 t_error("%s failed: result = %d\n", __func__, result);
133 }
134
135 result = sigismember(&set, sig);
136 if (result != 0) {
137 t_error("%s failed: result = %d\n", __func__, result);
138 }
139 }
140
141 /**
142 * @tc.name : sigset_0300
143 * @tc.desc : modifies the disposition of the signal sig with SIG_DFL
144 * @tc.level : Level 1
145 */
sigset_0300(void)146 void sigset_0300(void)
147 {
148 sigset_t set;
149 int result = prepare(&set);
150 if (result != 0) {
151 t_error("%s failed: result = %d\n", __func__, result);
152 }
153
154 result = sigemptyset(&set);
155 if (result != 0) {
156 t_error("%s failed: result = %d\n", __func__, result);
157 }
158
159 errno = 0;
160 sigset(sig, SIG_DFL);
161 if (errno != 0) {
162 t_error("%s failed: errno = %d\n", __func__, errno);
163 }
164
165 result = sigprocmask(SIG_BLOCK, NULL, &set);
166 if (result != 0) {
167 t_error("%s failed: result = %d\n", __func__, result);
168 }
169
170 result = sigismember(&set, sig);
171 if (result != 0) {
172 t_error("%s failed: result = %d\n", __func__, result);
173 }
174 }
175
176 /**
177 * @tc.name : sigset_0400
178 * @tc.desc : modifies the disposition of the signal sig with SIG_HOLD
179 * @tc.level : Level 1
180 */
sigset_0400(void)181 void sigset_0400(void)
182 {
183 sigset_t set;
184 int result = prepare(&set);
185 if (result != 0) {
186 t_error("%s failed: result = %d\n", __func__, result);
187 }
188
189 result = sigemptyset(&set);
190 if (result != 0) {
191 t_error("%s failed: result = %d\n", __func__, result);
192 }
193
194 errno = 0;
195 sigset(sig, SIG_HOLD);
196 if (errno != 0) {
197 t_error("%s failed: errno = %d\n", __func__, errno);
198 }
199
200 result = sigprocmask(SIG_BLOCK, NULL, &set);
201 if (result != 0) {
202 t_error("%s failed: result = %d\n", __func__, result);
203 }
204
205 result = sigismember(&set, sig);
206 if (result == 0) {
207 t_error("%s failed: result = %d\n", __func__, result);
208 }
209 }
210
211 /**
212 * @tc.name : sigset_0500
213 * @tc.desc : modifies the disposition of the invalid signal sig
214 * @tc.level : Level 2
215 */
sigset_0500(void)216 void sigset_0500(void)
217 {
218 errno = 0;
219 int sig = 99999;
220
221 sigset(sig, SIG_DFL);
222 if (errno == 0) {
223 t_error("%s failed: errno = %d\n", __func__, errno);
224 }
225 }
226
main(int argc,char * argv[])227 int main(int argc, char *argv[])
228 {
229 sigset_0100();
230 sigset_0200();
231 sigset_0300();
232 sigset_0400();
233 sigset_0500();
234
235 return t_status;
236 }
237