1 /*
2 * Copyright (c) 2023 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 <sigchain.h>
17 #include <signal.h>
18 #include <wchar.h>
19 #include <stdlib.h>
20 #include <errno.h>
21 #include "test.h"
22 #include "functionalext.h"
23 #include "sigchain_util.h"
24
25 static int g_count = 0;
26 #define ZERO (0)
27 #define VAL_INT (1024)
28
wait_until_sigabrt(void)29 void wait_until_sigabrt(void)
30 {
31 sigset_t set;
32 sigemptyset(&set);
33 sigaddset(&set, SIGABRT);
34 // 设置超时结构,设置超时为 0.5 秒
35 struct timespec timeout;
36 timeout.tv_sec = 0; // 秒部分为 0
37 timeout.tv_nsec = 500000000; // 纳秒部分为 500000000,即 0.5 秒
38 (void)sigtimedwait(&set, NULL, &timeout);
39 }
40
sigaction_abort(int signo,siginfo_t * info,void * context)41 static void sigaction_abort(int signo, siginfo_t *info, void *context)
42 {
43 EXPECT_EQ("sigchain_intercept_sigaction_000 check sival_int failed", info->si_value.sival_int, VAL_INT);
44 g_count++;
45 EXPECT_EQ("sigchain_intercept_sigaction_001", signo, SIGABRT);
46 }
47
48 /**
49 * @brief the SIGABRT handler
50 */
signal_handler_sigabrt(int signo)51 static void signal_handler_sigabrt(int signo)
52 {
53 g_count++;
54 EXPECT_EQ("sigchain_intercept_sigaction_002", signo, SIGABRT);
55 }
56
57 /**
58 * @brief the special handler
59 */
signal_handler1(int signo)60 static void signal_handler1(int signo)
61 {
62 g_count++;
63 EXPECT_EQ("sigchain_intercept_sigaction_001", signo, SIGHUP);
64 }
65
66 /**
67 * @tc.name : sigchain_intercept_sigaction_001
68 * @tc.desc : The signal is not registered with the special handler, test the influence of sigchain
69 * on sigaction.
70 * @tc.level : Level 0
71 */
sigchain_intercept_sigaction_001()72 static void sigchain_intercept_sigaction_001()
73 {
74 struct sigaction siga1 = {
75 .sa_handler = signal_handler1,
76 .sa_flags = SA_RESTART,
77 };
78 sigaction(SIGHUP, &siga1, NULL);
79
80 raise(SIGHUP);
81 EXPECT_EQ("sigchain_intercept_sigaction_001", g_count, SIGCHIAN_TEST_SIGNAL_NUM_1);
82 }
83
84 /**
85 * @brief the special handler
86 */
sigchain_special_handler2(int signo,siginfo_t * siginfo,void * ucontext_raw)87 static bool sigchain_special_handler2(int signo, siginfo_t *siginfo, void *ucontext_raw)
88 {
89 g_count++;
90 EXPECT_EQ("sigchain_intercept_sigaction_002", signo, SIGUSR2);
91 return false;
92 }
93
94 /**
95 * @brief the signal handler
96 */
signal_handler2(int signo)97 static void signal_handler2(int signo)
98 {
99 g_count++;
100 EXPECT_EQ("sigchain_intercept_sigaction_002", signo, SIGUSR2);
101 }
102
103
104 /**
105 * @tc.name : sigchain_intercept_sigaction_002
106 * @tc.desc : The signals is registered with the special handler, test the influence of sigchain on sigaction.
107 * @tc.level : Level 0
108 */
sigchain_intercept_sigaction_002()109 static void sigchain_intercept_sigaction_002()
110 {
111 g_count = 0;
112 struct signal_chain_action sigusr2 = {
113 .sca_sigaction = sigchain_special_handler2,
114 .sca_mask = {},
115 .sca_flags = 0,
116 };
117 add_special_signal_handler(SIGUSR2, &sigusr2);
118
119 struct sigaction siga2 = {
120 .sa_handler = signal_handler2,
121 .sa_flags = SA_RESTART,
122 };
123 sigaction(SIGUSR2, &siga2, NULL);
124
125 if (get_sigchain_mask_enable()) {
126 sigset_t set = {0};
127 int signo[SIGCHIAN_TEST_SIGNAL_NUM_1] = {SIGUSR2};
128 SIGCHAIN_TEST_SET_MASK(set, "sigchain_intercept_sigaction_002", signo, SIGCHIAN_TEST_SIGNAL_NUM_1);
129 }
130
131 raise(SIGUSR2);
132 EXPECT_EQ("sigchain_intercept_sigaction_002", g_count, SIGCHIAN_TEST_SIGNAL_NUM_2);
133 }
134
135 /**
136 * @brief the special handler
137 */
sigchain_special_handler3(int signo,siginfo_t * siginfo,void * ucontext_raw)138 static bool sigchain_special_handler3(int signo, siginfo_t *siginfo, void *ucontext_raw)
139 {
140 g_count++;
141 EXPECT_EQ("sigchain_intercept_sigaction_003", signo, SIGURG);
142 return false;
143 }
144
145 /**
146 * @brief the signal handler
147 */
signal_handler3(int signo)148 static void signal_handler3(int signo)
149 {
150 g_count++;
151 EXPECT_EQ("sigchain_intercept_sigaction_003", signo, SIGURG);
152 }
153
154 /**
155 * @tc.name : sigchain_intercept_sigaction_003
156 * @tc.desc : the signal is registered with the special handler, and remove the special handler. Test
157 * the influence of sigchain on sigaction.
158 * @tc.level : Level 0
159 */
sigchain_intercept_sigaction_003()160 static void sigchain_intercept_sigaction_003()
161 {
162 g_count = 0;
163 struct signal_chain_action sigurg = {
164 .sca_sigaction = sigchain_special_handler3,
165 .sca_mask = {},
166 .sca_flags = 0,
167 };
168 add_special_signal_handler(SIGURG, &sigurg);
169
170 struct sigaction siga2 = {
171 .sa_handler = signal_handler3,
172 .sa_flags = SA_RESTART,
173 };
174 sigaction(SIGURG, &siga2, NULL);
175
176 if (get_sigchain_mask_enable()) {
177 sigset_t set = {0};
178 int signo[SIGCHIAN_TEST_SIGNAL_NUM_1] = {SIGURG};
179 SIGCHAIN_TEST_SET_MASK(set, "sigchain_intercept_sigaction_003", signo, SIGCHIAN_TEST_SIGNAL_NUM_1);
180 }
181
182 remove_special_signal_handler(SIGURG, sigchain_special_handler3);
183 raise(SIGURG);
184 EXPECT_EQ("sigchain_intercept_sigaction_003", g_count, SIGCHIAN_TEST_SIGNAL_NUM_1);
185 }
186
187 /**
188 * @tc.name : sigchain_intercept_sigaction_sigabort
189 * @tc.desc : Test whether the user manually sets sa_sigaction for the SIGABRT signal to execute normally.
190 * Test whether the user manually sets sa_handler for the SIGABRT signal to execute normally.
191 * @tc.level : Level 0
192 */
sigchain_intercept_sigaction_sigabort(void)193 static void sigchain_intercept_sigaction_sigabort(void)
194 {
195 // 解除signal6的信号屏蔽
196 sigset_t remove_signal6_mask;
197 sigemptyset(&remove_signal6_mask);
198 sigaddset(&remove_signal6_mask, SIGABRT);
199 if (sigprocmask(SIG_UNBLOCK, &remove_signal6_mask, NULL) == -1) {
200 t_error("sigprocmask remove signal 6 failed errno=%d\n", errno);
201 }
202 g_count = 0;
203 struct sigaction action = {
204 .sa_sigaction = sigaction_abort,
205 .sa_flags = SA_SIGINFO,
206 };
207 int result = sigaction(SIGABRT, &action, NULL);
208 if (result != ZERO) {
209 t_error("sigchain_intercept_sigaction_sigabort sigaction 1 failed, errno=%d\n", errno);
210 }
211 // 1. 创建 sigval 结构体并设置附加数据,校验sa_sigaction场景是否有效,并校验参数是否已经带上
212 union sigval value;
213 value.sival_int = VAL_INT;
214 result = sigqueue(getpid(), SIGABRT, value);
215 if (result != ZERO) {
216 t_error("sigchain_intercept_sigaction_sigabort sigqueue failed errno=%d\n", errno);
217 return;
218 }
219 wait_until_sigabrt();
220 EXPECT_EQ("sigchain_intercept_sigaction_sigabort", g_count, SIGCHIAN_TEST_SIGNAL_NUM_1);
221
222 // 2. 清理状态
223 g_count = 0;
224 memset(&action, 0, sizeof(action));
225 action.sa_handler = SIG_DFL;
226 sigemptyset(&action.sa_mask);
227 action.sa_flags = 0;
228 result = sigaction(SIGABRT, &action, NULL);
229 if (result != ZERO) {
230 t_error("sigchain_intercept_sigaction_sigabort sigaction 2 failed, errno=%d\n", errno);
231 }
232 // 3. 使用sa_handler的方式处理sigabrt,并判断是否走到了信号处理函数
233 action.sa_handler = signal_handler_sigabrt;
234
235 action.sa_flags = SA_RESTART;
236 result = sigaction(SIGABRT, &action, NULL);
237 if (result != ZERO) {
238 t_error("sigchain_intercept_sigaction_sigabort sigaction 3 failed, errno=%d\n", errno);
239 }
240 (void)raise(SIGABRT);
241 wait_until_sigabrt();
242 EXPECT_EQ("sigchain_intercept_sigaction_sigabort", g_count, SIGCHIAN_TEST_SIGNAL_NUM_1);
243 }
244
main(void)245 int main(void)
246 {
247 sigchain_intercept_sigaction_001();
248 sigchain_intercept_sigaction_002();
249 sigchain_intercept_sigaction_003();
250 sigchain_intercept_sigaction_sigabort();
251 return t_status;
252 }