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