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 <wchar.h>
18 #include <stdlib.h>
19 #include "test.h"
20 #include "functionalext.h"
21 #include "sigchain_util.h"
22
23 static int g_count = 0;
24
25 /**
26 * @brief the special handler
27 */
sigchain_special_handler(int signo,siginfo_t * siginfo,void * ucontext_raw)28 static bool sigchain_special_handler(int signo, siginfo_t *siginfo, void *ucontext_raw)
29 {
30 EXPECT_EQ("sigchain_handler_call_order_001", signo, SIGHUP);
31 sigset_t set = {0};
32 int signal[SIGCHIAN_TEST_SIGNAL_NUM_2] = {SIGHUP, SIGUSR2};
33 SIGCHAIN_TEST_SET_MASK(set, "sigchain_handler_call_order_001", signal, SIGCHIAN_TEST_SIGNAL_NUM_2);
34 raise(SIGUSR2);
35 g_count++;
36 return false;
37 }
38
39 /**
40 * @brief the special handler
41 */
sigchain_special_handler1(int signo,siginfo_t * siginfo,void * ucontext_raw)42 static bool sigchain_special_handler1(int signo, siginfo_t *siginfo, void *ucontext_raw)
43 {
44 EXPECT_EQ("sigchain_handler_call_order_001", signo, SIGUSR2);
45 EXPECT_EQ("sigchain_handler_call_order_001", g_count, SIGCHIAN_TEST_SIGNAL_NUM_1);
46 g_count++;
47 return false;
48 }
49
50 /**
51 * @brief the signal handler
52 */
signal_handler(int signo)53 static void signal_handler(int signo)
54 {
55 g_count++;
56 }
57
58 /**
59 * @tc.name : sigchain_handler_call_order_001
60 * @tc.desc : The signals are registered with the special handler, and mask and rasie the signal
61 * at the special handler. Test the influence of sigchain on pthread_sigmask.
62 * @tc.level : Level 0
63 */
sigchain_handler_call_order_001()64 static void sigchain_handler_call_order_001()
65 {
66 signal(SIGHUP, signal_handler);
67 signal(SIGUSR2, signal_handler);
68
69 struct signal_chain_action sighup = {
70 .sca_sigaction = sigchain_special_handler,
71 .sca_mask = {},
72 .sca_flags = 0,
73 };
74 add_special_signal_handler(SIGHUP, &sighup);
75
76 struct signal_chain_action sigusr2 = {
77 .sca_sigaction = sigchain_special_handler1,
78 .sca_mask = {},
79 .sca_flags = 0,
80 };
81 add_special_signal_handler(SIGUSR2, &sigusr2);
82
83 raise(SIGHUP);
84 EXPECT_EQ("sigchain_handler_call_order_001", g_count, SIGCHIAN_TEST_SIGNAL_NUM_4);
85 }
86
87 /**
88 * @brief the special handler
89 */
sigchain_special_handler3(int signo,siginfo_t * siginfo,void * ucontext_raw)90 static bool sigchain_special_handler3(int signo, siginfo_t *siginfo, void *ucontext_raw)
91 {
92 EXPECT_EQ("sigchain_handler_call_order_002", signo, SIGPWR);
93 g_count++;
94 return false;
95 }
96
97 /**
98 * @brief the signal handler
99 */
signal_handler3(int signo)100 static void signal_handler3(int signo)
101 {
102 EXPECT_EQ("sigchain_handler_call_order_002", signo, SIGPWR);
103 EXPECT_EQ("sigchain_handler_call_order_002", g_count, SIGCHIAN_TEST_SIGNAL_NUM_1);
104 g_count++;
105 return;
106 }
107
108 /**
109 * @tc.name : sigchain_handler_call_order_002
110 * @tc.desc : Add a special handler for a signal that is registered with
111 * the kernel (Using signal interface) in sigchain.
112 * @tc.level : Level 0
113 */
sigchain_handler_call_order_002()114 static void sigchain_handler_call_order_002()
115 {
116 g_count = 0;
117 signal(SIGPWR, signal_handler3);
118
119 struct signal_chain_action sigsegv = {
120 .sca_sigaction = sigchain_special_handler3,
121 .sca_mask = {},
122 .sca_flags = 0,
123 };
124 add_special_signal_handler(SIGPWR, &sigsegv);
125
126 raise(SIGPWR);
127 EXPECT_EQ("sigchain_handler_call_order_002", g_count, SIGCHIAN_TEST_SIGNAL_NUM_2);
128 }
129
main(void)130 int main(void)
131 {
132 sigchain_handler_call_order_001();
133 sigchain_handler_call_order_002();
134 return t_status;
135 }