• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }