1/*
2 * Copyright (C) 2024 HiHope Open Source Organization.
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 <csignal>
17#include <unistd.h>
18#include <gtest/gtest.h>
19#include <sys/wait.h>
20
21using namespace testing::ext;
22
23static char g_stack[SIGSTKSZ];
24
25class HatsSigaltstackTest : public testing::Test {
26public:
27    static void SetUpTestCase();
28    static void TearDownTestCase();
29    void SetUp();
30    void TearDown();
31private:
32};
33void HatsSigaltstackTest::SetUp()
34{
35}
36void HatsSigaltstackTest::TearDown()
37{
38}
39void HatsSigaltstackTest::SetUpTestCase()
40{
41}
42void HatsSigaltstackTest::TearDownTestCase()
43{
44}
45
46static void Handle(int sig)
47{
48    int ret;
49    uintptr_t i;
50    uintptr_t* ptr;
51    stack_t ss;
52
53    ptr = reinterpret_cast<uintptr_t*>(&i);
54    EXPECT_TRUE(ptr >= reinterpret_cast<uintptr_t*>(g_stack));
55    EXPECT_TRUE(ptr < reinterpret_cast<uintptr_t*>(g_stack + SIGSTKSZ));
56    ret = sigaltstack(nullptr, &ss);
57    EXPECT_EQ(ret, 0);
58    EXPECT_EQ(ss.ss_flags, SS_ONSTACK);
59}
60
61/*
62 * @tc.number : SUB_KERNEL_SYSCALL_SIGALTSTACK_0100
63 * @tc.name   : SigaltstackParameterNormalProcessSuccess_0001
64 * @tc.desc   : sigaltstack parameter normal process success.
65 * @tc.size   : MediumTest
66 * @tc.type   : Function
67 * @tc.level  : Level 1
68 */
69HWTEST_F(HatsSigaltstackTest, SigaltstackParameterNormalProcessSuccess_0001, Function | MediumTest | Level1)
70{
71    int ret;
72    stack_t ss;
73    struct sigaction sa;
74
75    ss.ss_sp = g_stack;
76    ss.ss_size = sizeof(g_stack);
77    ss.ss_flags = 0;
78    sa.sa_handler = Handle;
79    sa.sa_flags = SA_ONSTACK;
80    ret = sigaltstack(&ss, nullptr);
81    EXPECT_EQ(ret, 0);
82    ret = sigfillset(&sa.sa_mask);
83    EXPECT_EQ(ret, 0);
84    ret = sigaction(SIGUSR1, &sa, nullptr);
85    EXPECT_EQ(ret, 0);
86    ret = raise(SIGUSR1);
87    EXPECT_EQ(ret, 0);
88}
89
90/*
91 * @tc.number : SUB_KERNEL_SYSCALL_SIGALTSTACK_0200
92 * @tc.name   : SigaltstackParameterAbnormalProcessFail_0002
93 * @tc.desc   : Sigaltstack paramter set fail, return -1, and set errno.
94 * @tc.size   : MediumTest
95 * @tc.type   : Function
96 * @tc.level  : Level 2
97 */
98HWTEST_F(HatsSigaltstackTest, SigaltstackParameterAbnormalProcessFail_0002, Function | MediumTest | Level2)
99{
100    int ret;
101    stack_t ss;
102    struct sigaction sa;
103
104    ss.ss_sp = g_stack;
105    ss.ss_size = sizeof(g_stack);
106    ss.ss_flags = 0;
107    sa.sa_handler = Handle;
108    sa.sa_flags = SA_ONSTACK;
109    errno = 0;
110    ss.ss_size = MINSIGSTKSZ - 1;
111    ret = sigaltstack(&ss, nullptr);
112    EXPECT_EQ(ret, -1);
113    EXPECT_EQ(errno, ENOMEM);
114
115    errno = 0;
116    ss.ss_flags = -1;
117    ss.ss_size = MINSIGSTKSZ;
118    ret =  sigaltstack(&ss, nullptr);
119    EXPECT_EQ(ret, -1);
120    EXPECT_EQ(errno, EINVAL);
121}
122