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 "test.h"
21#include "functionalext.h"
22#include "sigchain_util.h"
23
24static int g_count = 0;
25/**
26 * @brief the special handler
27 */
28static void signal_handler1(int signo)
29{
30    g_count++;
31    EXPECT_EQ("sigchain_intercept_sigaction_001", signo, SIGHUP);
32}
33
34/**
35 * @tc.name      : sigchain_intercept_sigaction_001
36 * @tc.desc      : The signal is not registered with the special handler, test the influence of sigchain
37 *                 on sigaction.
38 * @tc.level     : Level 0
39 */
40static void sigchain_intercept_sigaction_001()
41{
42    struct sigaction siga1 = {
43        .sa_handler = signal_handler1,
44        .sa_flags = SA_RESTART,
45    };
46    sigaction(SIGHUP, &siga1, NULL);
47
48    raise(SIGHUP);
49    EXPECT_EQ("sigchain_intercept_sigaction_001", g_count, SIGCHIAN_TEST_SIGNAL_NUM_1);
50}
51
52/**
53 * @brief the special handler
54 */
55static bool sigchain_special_handler2(int signo, siginfo_t *siginfo, void *ucontext_raw)
56{
57    g_count++;
58    EXPECT_EQ("sigchain_intercept_sigaction_002", signo, SIGUSR2);
59    return false;
60}
61
62/**
63 * @brief the signal handler
64 */
65static void signal_handler2(int signo)
66{
67    g_count++;
68    EXPECT_EQ("sigchain_intercept_sigaction_002", signo, SIGUSR2);
69}
70
71
72/**
73 * @tc.name      : sigchain_intercept_sigaction_002
74 * @tc.desc      : The signals is registered with the special handler, test the influence of sigchain on sigaction.
75 * @tc.level     : Level 0
76 */
77static void sigchain_intercept_sigaction_002()
78{
79    g_count = 0;
80    struct signal_chain_action sigusr2 = {
81        .sca_sigaction = sigchain_special_handler2,
82        .sca_mask = {},
83        .sca_flags = 0,
84    };
85    add_special_signal_handler(SIGUSR2, &sigusr2);
86
87    struct sigaction siga2 = {
88        .sa_handler = signal_handler2,
89        .sa_flags = SA_RESTART,
90    };
91    sigaction(SIGUSR2, &siga2, NULL);
92
93    if (get_sigchain_mask_enable()) {
94        sigset_t set = {0};
95        int signo[SIGCHIAN_TEST_SIGNAL_NUM_1] = {SIGUSR2};
96        SIGCHAIN_TEST_SET_MASK(set, "sigchain_intercept_sigaction_002", signo, SIGCHIAN_TEST_SIGNAL_NUM_1);
97    }
98
99    raise(SIGUSR2);
100    EXPECT_EQ("sigchain_intercept_sigaction_002", g_count, SIGCHIAN_TEST_SIGNAL_NUM_2);
101}
102
103/**
104 * @brief the special handler
105 */
106static bool sigchain_special_handler3(int signo, siginfo_t *siginfo, void *ucontext_raw)
107{
108    g_count++;
109    EXPECT_EQ("sigchain_intercept_sigaction_003", signo, SIGURG);
110    return false;
111}
112
113/**
114 * @brief the signal handler
115 */
116static void signal_handler3(int signo)
117{
118    g_count++;
119    EXPECT_EQ("sigchain_intercept_sigaction_003", signo, SIGURG);
120}
121
122/**
123 * @tc.name      : sigchain_intercept_sigaction_003
124 * @tc.desc      : the signal is registered with the special handler, and remove the special handler. Test
125 *                 the influence of sigchain on sigaction.
126 * @tc.level     : Level 0
127 */
128static void sigchain_intercept_sigaction_003()
129{
130    g_count = 0;
131    struct signal_chain_action sigurg = {
132        .sca_sigaction = sigchain_special_handler3,
133        .sca_mask = {},
134        .sca_flags = 0,
135    };
136    add_special_signal_handler(SIGURG, &sigurg);
137
138    struct sigaction siga2 = {
139        .sa_handler = signal_handler3,
140        .sa_flags = SA_RESTART,
141    };
142    sigaction(SIGURG, &siga2, NULL);
143
144    if (get_sigchain_mask_enable()) {
145        sigset_t set = {0};
146        int signo[SIGCHIAN_TEST_SIGNAL_NUM_1] = {SIGURG};
147        SIGCHAIN_TEST_SET_MASK(set, "sigchain_intercept_sigaction_003", signo, SIGCHIAN_TEST_SIGNAL_NUM_1);
148    }
149
150    remove_special_signal_handler(SIGURG, sigchain_special_handler3);
151    raise(SIGURG);
152    EXPECT_EQ("sigchain_intercept_sigaction_003", g_count, SIGCHIAN_TEST_SIGNAL_NUM_1);
153}
154
155int main(void)
156{
157    sigchain_intercept_sigaction_001();
158    sigchain_intercept_sigaction_002();
159    sigchain_intercept_sigaction_003();
160    return t_status;
161}