Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party Musl
提交
0030a18d
T
Third Party Musl
项目概览
OpenHarmony
/
Third Party Musl
大约 1 年 前同步成功
通知
37
Star
125
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
Third Party Musl
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
0030a18d
编写于
2月 22, 2023
作者:
O
openharmony_ci
提交者:
Gitee
2月 22, 2023
浏览文件
操作
浏览文件
下载
差异文件
!788 SigChain功能实现
Merge pull request !788 from dhy308/release_sigchain_0113
上级
7238de0b
9e1d42fb
变更
17
显示空白变更内容
内联
并排
Showing
17 changed file
with
2047 addition
and
0 deletion
+2047
-0
libc-test/src/functionalext/common/sigchain_util.h
libc-test/src/functionalext/common/sigchain_util.h
+53
-0
libc-test/src/functionalext/sigchain/BUILD.gn
libc-test/src/functionalext/sigchain/BUILD.gn
+28
-0
libc-test/src/functionalext/sigchain/sigchain_add_special_handler.c
...src/functionalext/sigchain/sigchain_add_special_handler.c
+391
-0
libc-test/src/functionalext/sigchain/sigchain_handler_call_order.c
.../src/functionalext/sigchain/sigchain_handler_call_order.c
+134
-0
libc-test/src/functionalext/sigchain/sigchain_intercept_sigaction.c
...src/functionalext/sigchain/sigchain_intercept_sigaction.c
+155
-0
libc-test/src/functionalext/sigchain/sigchain_intercept_signal.c
...st/src/functionalext/sigchain/sigchain_intercept_signal.c
+143
-0
libc-test/src/functionalext/sigchain/sigchain_intercept_sigprocmask.c
...c/functionalext/sigchain/sigchain_intercept_sigprocmask.c
+182
-0
libc-test/src/functionalext/sigchain/sigchain_rm_special_handler.c
.../src/functionalext/sigchain/sigchain_rm_special_handler.c
+355
-0
libc-test/src/functionalext/sigchain/test_src_functionalext_sigchain.gni
...unctionalext/sigchain/test_src_functionalext_sigchain.gni
+20
-0
libc-test/src/functionalext/test_src_functionalext.gni
libc-test/src/functionalext/test_src_functionalext.gni
+1
-0
libc-test/test_template.gni
libc-test/test_template.gni
+4
-0
libc.map.txt
libc.map.txt
+2
-0
musl_src.gni
musl_src.gni
+6
-0
porting/linux/user/include/sigchain.h
porting/linux/user/include/sigchain.h
+48
-0
porting/linux/user/src/sigchain/sigchain.c
porting/linux/user/src/sigchain/sigchain.c
+385
-0
porting/linux/user/src/signal/sigaction.c
porting/linux/user/src/signal/sigaction.c
+95
-0
porting/linux/user/src/signal/sigprocmask.c
porting/linux/user/src/signal/sigprocmask.c
+45
-0
未找到文件。
libc-test/src/functionalext/common/sigchain_util.h
0 → 100644
浏览文件 @
0030a18d
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* SIG_BLOCK: Mask the signal according to the mask word provided by parameter set.
* And save the original signal mask to oldset
*/
#define SIGCHAIN_TEST_SET_MASK(set, fun, signo, num) do{ \
int result = sigemptyset(&set); \
if (result != 0) { \
EXPECT_FALSE(fun, true); \
} \
for (int i = 0; i < num; i++) { \
result = sigaddset(&set, signo[i]); \
if (result != 0) { \
EXPECT_FALSE(fun, true); \
} \
} \
result = sigprocmask(SIG_BLOCK, &set, NULL); \
if (result != 0) { \
EXPECT_FALSE(fun, true); \
} \
} while (0)
#define SIGCHIAN_TEST_SIGNAL_NUM_1 1
#define SIGCHIAN_TEST_SIGNAL_NUM_2 2
#define SIGCHIAN_TEST_SIGNAL_NUM_3 3
#define SIGCHIAN_TEST_SIGNAL_NUM_4 4
#define SIGCHIAN_TEST_SIGNAL_NUM_5 5
#define SIGCHIAN_TEST_SIGNAL_NUM_6 6
#define SIGCHIAN_TEST_SIGNAL_NUM_8 8
#define SIGCHIAN_TEST_SIGNAL_NUM_9 9
#define SIGCHIAN_TEST_SIGNAL_NUM_11 11
#define SIGCHIAN_TEST_SIGNAL_NUM_13 13
#define SIGCHIAN_TEST_SIGNAL_NUM_14 14
#define SIGCHAIN_SIGNAL_37 37
#define SIGCHAIN_SIGNAL_43 43
#define SIGCHAIN_SIGNAL_64 64
extern
bool
get_sigchain_mask_enable
();
\ No newline at end of file
libc-test/src/functionalext/sigchain/BUILD.gn
0 → 100644
浏览文件 @
0030a18d
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("../../../test_template.gni")
import("test_src_functionalext_sigchain.gni")
foreach(s, functionalext_sigchain_list) {
test_unittest(s) {
target_dir = "functionalext/sigchain"
}
}
group("functionalext_sigchain_test") {
testonly = true
deps = []
foreach(s, functionalext_sigchain_list) {
deps += [ ":${s}" ]
}
}
libc-test/src/functionalext/sigchain/sigchain_add_special_handler.c
0 → 100644
浏览文件 @
0030a18d
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sigchain.h>
#include <wchar.h>
#include <stdlib.h>
#include "test.h"
#include "functionalext.h"
#include "sigchain_util.h"
static
int
g_count
=
0
;
/**
* @brief the special handler
*/
static
bool
sigchain_special_sigabrt_handler1
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_add_special_handler_001"
,
signo
,
SIGABRT
);
return
false
;
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_sigabrt_handler2
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_add_special_handler_001"
,
signo
,
SIGABRT
);
return
true
;
}
/**
* @tc.name : sigchain_add_special_handler_001
* @tc.desc : The signal are not registered with the kernel, call add_special_signal_handler to add
* two special handlers
* @tc.level : Level 0
*/
static
void
sigchain_add_special_handler_001
()
{
struct
signal_chain_action
sigabrt
=
{
.
sca_sigaction
=
sigchain_special_sigabrt_handler1
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGABRT
,
&
sigabrt
);
struct
signal_chain_action
sigabrt1
=
{
.
sca_sigaction
=
sigchain_special_sigabrt_handler2
,
.
sca_mask
=
{},
.
sca_flags
=
SIGCHAIN_ALLOW_NORETURN
,
};
add_special_signal_handler
(
SIGABRT
,
&
sigabrt1
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGABRT
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_add_special_handler_001"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
raise
(
SIGABRT
);
EXPECT_EQ
(
"sigchain_add_special_handler_001"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_2
);
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_sighup_handler1
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_add_special_handler_002"
,
signo
,
SIGHUP
);
return
false
;
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_sighup_handler2
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_add_special_handler_002"
,
signo
,
SIGHUP
);
return
false
;
}
/**
* @brief the signal handler
*/
static
void
signal_sighup_handler
(
int
signo
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_add_special_handler_002"
,
signo
,
SIGHUP
);
}
/**
* @tc.name : sigchain_add_special_handler_002
* @tc.desc : The signal are registered with the kernel(Using signal), call
* add_special_signal_handler to add two special handlers
* @tc.level : Level 0
*/
static
void
sigchain_add_special_handler_002
()
{
signal
(
SIGHUP
,
signal_sighup_handler
);
struct
signal_chain_action
sighup
=
{
.
sca_sigaction
=
sigchain_special_sighup_handler1
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGHUP
,
&
sighup
);
struct
signal_chain_action
sighup1
=
{
.
sca_sigaction
=
sigchain_special_sighup_handler2
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGHUP
,
&
sighup1
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGHUP
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_add_special_handler_002"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
raise
(
SIGHUP
);
EXPECT_EQ
(
"sigchain_add_special_handler_002"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_5
);
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_sigsegv_handler1
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_add_special_handler_003"
,
signo
,
SIGSEGV
);
return
false
;
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_sigsegv_handler2
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_add_special_handler_003"
,
signo
,
SIGSEGV
);
return
false
;
}
/**
* @brief the signal handler
*/
static
void
signal_sigsegv_sigaction
(
int
signo
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_add_special_handler_003"
,
signo
,
SIGSEGV
);
}
/**
* @tc.name : sigchain_add_special_handler_003
* @tc.desc : the signal that are registered with the kernel(Using sigaction), call
* add_special_signal_handler to add two special handlers
* @tc.level : Level 0
*/
static
void
sigchain_add_special_handler_003
()
{
struct
sigaction
sigac
=
{
.
sa_handler
=
signal_sigsegv_sigaction
,
};
sigaction
(
SIGSEGV
,
&
sigac
,
NULL
);
struct
signal_chain_action
sigsegv
=
{
.
sca_sigaction
=
sigchain_special_sigsegv_handler1
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGSEGV
,
&
sigsegv
);
struct
signal_chain_action
sigsegv2
=
{
.
sca_sigaction
=
sigchain_special_sigsegv_handler2
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGSEGV
,
&
sigsegv2
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGSEGV
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_add_special_handler_003"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
raise
(
SIGSEGV
);
EXPECT_EQ
(
"sigchain_add_special_handler_003"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_8
);
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_sigterm_handler
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_add_special_handler_004"
,
signo
,
SIGTERM
);
return
true
;
}
/**
* @tc.name : sigchain_add_special_handler_004
* @tc.desc : the signal is not registered with the kernel, call add_special_signal_handler to add
* a special handler.
* @tc.level : Level 0
*/
static
void
sigchain_add_special_handler_004
()
{
struct
signal_chain_action
sigterm
=
{
.
sca_sigaction
=
sigchain_special_sigterm_handler
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGTERM
,
&
sigterm
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGTERM
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_add_special_handler_004"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
raise
(
SIGTERM
);
EXPECT_EQ
(
"sigchain_add_special_handler_004"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_9
);
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_64_handler
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
EXPECT_EQ
(
"sigchain_add_special_handler_005"
,
signo
,
SIGCHAIN_SIGNAL_64
);
g_count
++
;
return
false
;
}
/**
* @brief the signal handler
*/
static
void
signal_64_handler
(
int
signo
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_add_special_handler_005"
,
signo
,
SIGCHAIN_SIGNAL_64
);
}
/**
* @tc.name : sigchain_add_special_handler_005
* @tc.desc : the signal is registered with the kernel(Using signal), call add_special_signal_handler to add
* a special handler.
* @tc.level : Level 0
*/
static
void
sigchain_add_special_handler_005
()
{
signal
(
SIGCHAIN_SIGNAL_64
,
signal_64_handler
);
struct
signal_chain_action
sighup
=
{
.
sca_sigaction
=
sigchain_special_64_handler
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGCHAIN_SIGNAL_64
,
&
sighup
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGCHAIN_SIGNAL_64
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_add_special_handler_005"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
raise
(
SIGCHAIN_SIGNAL_64
);
EXPECT_EQ
(
"sigchain_add_special_handler_005"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_11
);
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_37_handler
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_add_special_handler_006"
,
signo
,
SIGCHAIN_SIGNAL_37
);
return
false
;
}
/**
* @brief the signal handler
*/
static
void
signal_37_sigaction
(
int
signo
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_add_special_handler_006"
,
signo
,
SIGCHAIN_SIGNAL_37
);
}
/**
* @tc.name : sigchain_add_special_handler_006
* @tc.desc : the signal is registered with the kernel(Using sigaction), call add_special_signal_handler
* to add a special handler.
* @tc.level : Level 0
*/
static
void
sigchain_add_special_handler_006
()
{
struct
sigaction
sigac
=
{
.
sa_handler
=
signal_37_sigaction
,
};
sigaction
(
SIGCHAIN_SIGNAL_37
,
&
sigac
,
NULL
);
struct
signal_chain_action
sig37
=
{
.
sca_sigaction
=
sigchain_special_37_handler
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGCHAIN_SIGNAL_37
,
&
sig37
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGCHAIN_SIGNAL_37
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_add_special_handler_006"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
raise
(
SIGCHAIN_SIGNAL_37
);
EXPECT_EQ
(
"sigchain_add_special_handler_006"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_13
);
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_43_handler
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_add_special_handler_007"
,
signo
,
SIGCHAIN_SIGNAL_43
);
return
true
;
}
/**
* @brief the signal handler
*/
static
void
signal_43_sigaction
(
int
signo
)
{
g_count
++
;
EXPECT_FALSE
(
"sigchain_intercept_sigprocmask_003"
,
true
);
}
/**
* @tc.name : sigchain_add_special_handler_007
* @tc.desc : Multiple signal are registered with the kernel(Using sigaction), sigchain_special_43_handler return
* true.
* @tc.level : Level 0
*/
static
void
sigchain_add_special_handler_007
()
{
struct
sigaction
sigac
=
{
.
sa_handler
=
signal_43_sigaction
,
};
sigaction
(
SIGCHAIN_SIGNAL_43
,
&
sigac
,
NULL
);
struct
signal_chain_action
sig43
=
{
.
sca_sigaction
=
sigchain_special_43_handler
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGCHAIN_SIGNAL_43
,
&
sig43
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGCHAIN_SIGNAL_43
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_add_special_handler_007"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
raise
(
SIGCHAIN_SIGNAL_43
);
EXPECT_EQ
(
"sigchain_add_special_handler_007"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_14
);
}
int
main
(
void
)
{
sigchain_add_special_handler_001
();
sigchain_add_special_handler_002
();
sigchain_add_special_handler_003
();
sigchain_add_special_handler_004
();
sigchain_add_special_handler_005
();
sigchain_add_special_handler_006
();
sigchain_add_special_handler_007
();
return
t_status
;
}
\ No newline at end of file
libc-test/src/functionalext/sigchain/sigchain_handler_call_order.c
0 → 100644
浏览文件 @
0030a18d
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sigchain.h>
#include <wchar.h>
#include <stdlib.h>
#include "test.h"
#include "functionalext.h"
#include "sigchain_util.h"
static
int
g_count
=
0
;
/**
* @brief the special handler
*/
static
bool
sigchain_special_handler
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
EXPECT_EQ
(
"sigchain_handler_call_order_001"
,
signo
,
SIGHUP
);
sigset_t
set
=
{
0
};
int
signal
[
SIGCHIAN_TEST_SIGNAL_NUM_2
]
=
{
SIGHUP
,
SIGSEGV
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_intercept_sigprocmask_001"
,
signal
,
SIGCHIAN_TEST_SIGNAL_NUM_2
);
raise
(
SIGSEGV
);
g_count
++
;
return
false
;
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_handler1
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
EXPECT_EQ
(
"sigchain_handler_call_order_001"
,
signo
,
SIGSEGV
);
EXPECT_EQ
(
"sigchain_handler_call_order_001"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
g_count
++
;
return
false
;
}
/**
* @brief the signal handler
*/
static
void
signal_handler
(
int
signo
)
{
g_count
++
;
}
/**
* @tc.name : sigchain_handler_call_order_001
* @tc.desc : The signals are registered with the special handler, and mask and rasie the signal
* at the special handler. Test the influence of sigchain on sigprocmask.
* @tc.level : Level 0
*/
static
void
sigchain_handler_call_order_001
()
{
signal
(
SIGHUP
,
signal_handler
);
signal
(
SIGSEGV
,
signal_handler
);
struct
signal_chain_action
sighup
=
{
.
sca_sigaction
=
sigchain_special_handler
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGHUP
,
&
sighup
);
struct
signal_chain_action
sigsegv
=
{
.
sca_sigaction
=
sigchain_special_handler1
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGSEGV
,
&
sigsegv
);
raise
(
SIGHUP
);
EXPECT_EQ
(
"sigchain_handler_call_order_001"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_4
);
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_handler3
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
EXPECT_EQ
(
"sigchain_handler_call_order_002"
,
signo
,
SIGSYS
);
g_count
++
;
return
false
;
}
/**
* @brief the signal handler
*/
static
void
signal_handler3
(
int
signo
)
{
EXPECT_EQ
(
"sigchain_handler_call_order_002"
,
signo
,
SIGSYS
);
EXPECT_EQ
(
"sigchain_handler_call_order_002"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_5
);
g_count
++
;
return
;
}
/**
* @tc.name : sigchain_handler_call_order_002
* @tc.desc : Add a special handler for a signal that is registered with
* the kernel (Using signal interface) in sigchain.
* @tc.level : Level 0
*/
static
void
sigchain_handler_call_order_002
()
{
signal
(
SIGSYS
,
signal_handler3
);
struct
signal_chain_action
sigsegv
=
{
.
sca_sigaction
=
sigchain_special_handler3
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGSYS
,
&
sigsegv
);
raise
(
SIGSYS
);
EXPECT_EQ
(
"sigchain_handler_call_order_002"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_6
);
}
int
main
(
void
)
{
sigchain_handler_call_order_001
();
sigchain_handler_call_order_002
();
return
t_status
;
}
\ No newline at end of file
libc-test/src/functionalext/sigchain/sigchain_intercept_sigaction.c
0 → 100644
浏览文件 @
0030a18d
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sigchain.h>
#include <signal.h>
#include <wchar.h>
#include <stdlib.h>
#include "test.h"
#include "functionalext.h"
#include "sigchain_util.h"
static
int
g_count
=
0
;
/**
* @brief the special handler
*/
static
void
signal_handler1
(
int
signo
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_intercept_sigaction_001"
,
signo
,
SIGHUP
);
}
/**
* @tc.name : sigchain_intercept_sigaction_001
* @tc.desc : The signals are not registered with the special handler, test the influence of sigchain
* on sigaction.
* @tc.level : Level 0
*/
static
void
sigchain_intercept_sigaction_001
()
{
struct
sigaction
siga1
=
{
.
sa_handler
=
signal_handler1
,
};
sigaction
(
SIGHUP
,
&
siga1
,
NULL
);
raise
(
SIGHUP
);
EXPECT_EQ
(
"sigchain_intercept_sigaction_001"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_handler2
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_intercept_sigaction_002"
,
signo
,
SIGSEGV
);
return
false
;
}
/**
* @brief the signal handler
*/
static
void
signal_handler2
(
int
signo
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_intercept_sigaction_002"
,
signo
,
SIGSEGV
);
}
/**
* @tc.name : sigchain_intercept_sigaction_002
* @tc.desc : The signals are registered with the special handler, test the influence of sigchain on sigaction.
* @tc.level : Level 0
*/
static
void
sigchain_intercept_sigaction_002
()
{
struct
signal_chain_action
sigsegv
=
{
.
sca_sigaction
=
sigchain_special_handler2
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGSEGV
,
&
sigsegv
);
struct
sigaction
siga2
=
{
.
sa_handler
=
signal_handler2
,
};
sigaction
(
SIGSEGV
,
&
siga2
,
NULL
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGSEGV
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_intercept_sigaction_002"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
raise
(
SIGSEGV
);
EXPECT_EQ
(
"sigchain_intercept_sigaction_002"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_3
);
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_handler3
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_intercept_sigaction_003"
,
signo
,
SIGURG
);
return
false
;
}
/**
* @brief the signal handler
*/
static
void
signal_handler3
(
int
signo
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_intercept_sigaction_003"
,
signo
,
SIGURG
);
}
/**
* @tc.name : sigchain_intercept_sigaction_003
* @tc.desc : the signals are registered with the special handler, and remove the special handler. Test
* the influence of sigchain on sigaction.
* @tc.level : Level 0
*/
static
void
sigchain_intercept_sigaction_003
()
{
struct
signal_chain_action
sigurg
=
{
.
sca_sigaction
=
sigchain_special_handler3
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGURG
,
&
sigurg
);
struct
sigaction
siga2
=
{
.
sa_handler
=
signal_handler3
,
};
sigaction
(
SIGURG
,
&
siga2
,
NULL
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGURG
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_intercept_sigaction_002"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
remove_special_signal_handler
(
SIGURG
,
sigchain_special_handler3
);
raise
(
SIGURG
);
EXPECT_EQ
(
"sigchain_intercept_sigaction_003"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_4
);
}
int
main
(
void
)
{
sigchain_intercept_sigaction_001
();
sigchain_intercept_sigaction_002
();
sigchain_intercept_sigaction_003
();
return
t_status
;
}
\ No newline at end of file
libc-test/src/functionalext/sigchain/sigchain_intercept_signal.c
0 → 100644
浏览文件 @
0030a18d
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sigchain.h>
#include <signal.h>
#include <wchar.h>
#include <stdlib.h>
#include "test.h"
#include "functionalext.h"
#include "sigchain_util.h"
static
int
g_count
=
0
;
/**
* @brief the signal handler
*/
static
void
signal_handler1
(
int
signo
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_intercept_signal_001"
,
signo
,
SIGHUP
);
}
/**
* @tc.name : sigchain_add_special_handler_025
* @tc.desc : The signals are not registered with the special handler, test the influence of sigchain on signal
* @tc.level : Level 0
*/
static
void
sigchain_intercept_signal_001
()
{
signal
(
SIGHUP
,
signal_handler1
);
raise
(
SIGHUP
);
EXPECT_EQ
(
"sigchain_intercept_signal_001"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_handler1
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_intercept_signal_002"
,
signo
,
SIGSEGV
);
return
false
;
}
/**
* @brief the signal handler
*/
static
void
signal_handler2
(
int
signo
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_intercept_signal_002"
,
signo
,
SIGSEGV
);
}
/**
* @tc.name : sigchain_intercept_signal_002
* @tc.desc : The signals are registered with the special handler, test the influence of sigchain on signal
* @tc.level : Level 0
*/
static
void
sigchain_intercept_signal_002
()
{
struct
signal_chain_action
sigsegv
=
{
.
sca_sigaction
=
sigchain_special_handler1
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGSEGV
,
&
sigsegv
);
signal
(
SIGSEGV
,
signal_handler2
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGSEGV
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_intercept_signal_002"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
raise
(
SIGSEGV
);
EXPECT_EQ
(
"sigchain_intercept_signal_002"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_3
);
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_handler3
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_intercept_signal_003"
,
signo
,
SIGURG
);
return
false
;
}
/**
* @brief the signal handler
*/
static
void
signal_handler3
(
int
signo
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_intercept_signal_003"
,
signo
,
SIGURG
);
}
/**
* @tc.name : sigchain_intercept_signal_003
* @tc.desc : The signals are registered with the special handler, and remove the special handler.
* Test the influence of sigchain on signal
* @tc.level : Level 0
*/
static
void
sigchain_intercept_signal_003
()
{
struct
signal_chain_action
sigurg
=
{
.
sca_sigaction
=
sigchain_special_handler3
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGURG
,
&
sigurg
);
signal
(
SIGURG
,
signal_handler3
);
remove_special_signal_handler
(
SIGURG
,
sigchain_special_handler3
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGURG
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_intercept_sigaction_002"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
raise
(
SIGURG
);
EXPECT_EQ
(
"sigchain_intercept_signal_003"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_4
);
}
int
main
(
void
)
{
sigchain_intercept_signal_001
();
sigchain_intercept_signal_002
();
sigchain_intercept_signal_003
();
return
t_status
;
}
\ No newline at end of file
libc-test/src/functionalext/sigchain/sigchain_intercept_sigprocmask.c
0 → 100644
浏览文件 @
0030a18d
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sigchain.h>
#include <signal.h>
#include <wchar.h>
#include <stdlib.h>
#include "test.h"
#include "functionalext.h"
#include "sigchain_util.h"
static
int
g_count
=
0
;
/**
* @brief the special handler
*/
static
bool
sigchain_special_handler2
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_intercept_sigprocmask_001"
,
signo
,
SIGSEGV
);
return
false
;
}
/**
* @brief the signal handler
*/
static
void
signal_handler2
(
int
signo
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_intercept_sigprocmask_001"
,
signo
,
SIGSEGV
);
}
/**
* @tc.name : sigchain_intercept_sigprocmask_001
* @tc.desc : The signals are registered with the special handler, test the influence of sigchain
* on sigprocmask.
* @tc.level : Level 0
*/
static
void
sigchain_intercept_sigprocmask_001
()
{
struct
sigaction
siga2
=
{
.
sa_handler
=
signal_handler2
,
};
sigaction
(
SIGSEGV
,
&
siga2
,
NULL
);
struct
signal_chain_action
sigsegv
=
{
.
sca_sigaction
=
sigchain_special_handler2
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGSEGV
,
&
sigsegv
);
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGSEGV
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_intercept_sigprocmask_001"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
raise
(
SIGSEGV
);
if
(
get_sigchain_mask_enable
())
{
EXPECT_EQ
(
"sigchain_intercept_sigprocmask_001"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_2
);
}
else
{
EXPECT_EQ
(
"sigchain_intercept_sigprocmask_001"
,
g_count
,
0
);
}
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_handler3
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_FALSE
(
"sigchain_intercept_sigprocmask_002"
,
true
);
return
false
;
}
/**
* @brief the signal handler
*/
static
void
signal_handler3
(
int
signo
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_intercept_sigprocmask_002"
,
signo
,
SIGSYS
);
}
/**
* @tc.name : sigchain_intercept_sigprocmask_002
* @tc.desc : The signals are registered with the special handler, and remove the special handler.
* Test the influence of sigchain on sigprocmask.
* @tc.level : Level 0
*/
static
void
sigchain_intercept_sigprocmask_002
()
{
struct
sigaction
siga2
=
{
.
sa_handler
=
signal_handler3
,
};
sigaction
(
SIGSYS
,
&
siga2
,
NULL
);
struct
signal_chain_action
sigsegv
=
{
.
sca_sigaction
=
sigchain_special_handler3
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGSYS
,
&
sigsegv
);
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGSYS
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_intercept_sigprocmask_002"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
remove_special_signal_handler
(
SIGSYS
,
sigchain_special_handler3
);
raise
(
SIGSYS
);
if
(
get_sigchain_mask_enable
())
{
EXPECT_EQ
(
"sigchain_intercept_sigprocmask_002"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_3
);
}
else
{
EXPECT_EQ
(
"sigchain_intercept_sigprocmask_002"
,
g_count
,
0
);
}
}
/**
* @brief the signal handler
*/
static
void
signal_handler1
(
int
signo
)
{
g_count
++
;
EXPECT_FALSE
(
"sigchain_intercept_sigprocmask_001"
,
true
);
}
/**
* @tc.name : sigchain_intercept_sigprocmask_003
* @tc.desc : The signals are not registered with the special handler, test the influence of sigchain
* on sigprocmask.
* @tc.level : Level 0
*/
static
void
sigchain_intercept_sigprocmask_003
()
{
struct
sigaction
siga1
=
{
.
sa_handler
=
signal_handler1
,
};
sigaction
(
SIGHUP
,
&
siga1
,
NULL
);
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGHUP
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_intercept_sigprocmask_003"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
raise
(
SIGHUP
);
if
(
get_sigchain_mask_enable
())
{
EXPECT_EQ
(
"sigchain_intercept_sigprocmask_003"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_3
);
}
else
{
EXPECT_EQ
(
"sigchain_intercept_sigprocmask_003"
,
g_count
,
0
);
}
}
/**
* @tc.name : sigchain_intercept_sigprocmask_004
* @tc.desc : The new set is null, call sigprocmask.
* @tc.level : Level 0
*/
static
void
sigchain_intercept_sigprocmask_004
()
{
int
result
=
sigprocmask
(
SIG_BLOCK
,
NULL
,
NULL
);
if
(
result
!=
0
)
{
EXPECT_FALSE
(
"sigchain_intercept_sigprocmask_004"
,
true
);
}
}
int
main
(
void
)
{
sigchain_intercept_sigprocmask_001
();
sigchain_intercept_sigprocmask_002
();
sigchain_intercept_sigprocmask_003
();
sigchain_intercept_sigprocmask_004
();
return
t_status
;
}
\ No newline at end of file
libc-test/src/functionalext/sigchain/sigchain_rm_special_handler.c
0 → 100644
浏览文件 @
0030a18d
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sigchain.h>
#include <wchar.h>
#include <stdlib.h>
#include "test.h"
#include "functionalext.h"
#include "sigchain_util.h"
static
int
g_count
=
0
;
/**
* @brief the special handler
*/
static
bool
sigchain_special_sigabrt_handler1
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_FALSE
(
"sigchain_rm_special_handler_001"
,
true
);
return
false
;
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_sigabrt_handler2
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_FALSE
(
"sigchain_rm_special_handler_001"
,
true
);
return
true
;
}
/**
* @tc.name : sigchain_rm_special_handler_001
* @tc.desc : The signal are not registered with the kernel, call remove_special_signal_handler to remove
* two special handlers
* @tc.level : Level 0
*/
static
void
sigchain_rm_special_handler_001
()
{
struct
signal_chain_action
sigabrt
=
{
.
sca_sigaction
=
sigchain_special_sigabrt_handler1
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGABRT
,
&
sigabrt
);
struct
signal_chain_action
sigabrt1
=
{
.
sca_sigaction
=
sigchain_special_sigabrt_handler2
,
.
sca_mask
=
{},
.
sca_flags
=
SIGCHAIN_ALLOW_NORETURN
,
};
add_special_signal_handler
(
SIGABRT
,
&
sigabrt1
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGABRT
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_rm_special_handler_001"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
remove_special_signal_handler
(
SIGABRT
,
sigchain_special_sigabrt_handler1
);
remove_special_signal_handler
(
SIGABRT
,
sigchain_special_sigabrt_handler2
);
raise
(
SIGABRT
);
EXPECT_EQ
(
"sigchain_rm_special_handler_001"
,
g_count
,
0
);
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_sighup_handler1
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_FALSE
(
"sigchain_rm_special_handler_002"
,
true
);
return
false
;
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_sighup_handler2
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_FALSE
(
"sigchain_rm_special_handler_002"
,
true
);
return
false
;
}
/**
* @brief the signal handler
*/
static
void
signal_sighup_handler
(
int
signo
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_rm_special_handler_002"
,
signo
,
SIGHUP
);
}
/**
* @tc.name : sigchain_rm_special_handler_002
* @tc.desc : The signal are registered with the kernel(Using signal), call
* remove_special_signal_handler to remove two special handlers
* @tc.level : Level 0
*/
static
void
sigchain_rm_special_handler_002
()
{
signal
(
SIGHUP
,
signal_sighup_handler
);
struct
signal_chain_action
sighup
=
{
.
sca_sigaction
=
sigchain_special_sighup_handler1
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGHUP
,
&
sighup
);
struct
signal_chain_action
sighup1
=
{
.
sca_sigaction
=
sigchain_special_sighup_handler2
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGHUP
,
&
sighup1
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGHUP
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_rm_special_handler_002"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
remove_special_signal_handler
(
SIGHUP
,
sigchain_special_sighup_handler1
);
remove_special_signal_handler
(
SIGHUP
,
sigchain_special_sighup_handler2
);
raise
(
SIGHUP
);
EXPECT_EQ
(
"sigchain_rm_special_handler_002"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_sigsegv_handler1
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_FALSE
(
"sigchain_rm_special_handler_003"
,
true
);
return
false
;
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_sigsegv_handler2
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_FALSE
(
"sigchain_rm_special_handler_003"
,
true
);
return
false
;
}
/**
* @brief the signal handler
*/
static
void
signal_sigsegv_sigaction
(
int
signo
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_rm_special_handler_003"
,
signo
,
SIGSEGV
);
}
/**
* @tc.name : sigchain_rm_special_handler_003
* @tc.desc : the signal that are registered with the kernel(Using sigaction), call
* remove_special_signal_handler to remove two special handlers
* @tc.level : Level 0
*/
static
void
sigchain_rm_special_handler_003
()
{
struct
sigaction
sigac
=
{
.
sa_handler
=
signal_sigsegv_sigaction
,
};
sigaction
(
SIGSEGV
,
&
sigac
,
NULL
);
struct
signal_chain_action
sigsegv
=
{
.
sca_sigaction
=
sigchain_special_sigsegv_handler1
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGSEGV
,
&
sigsegv
);
struct
signal_chain_action
sigsegv2
=
{
.
sca_sigaction
=
sigchain_special_sigsegv_handler2
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGSEGV
,
&
sigsegv2
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGSEGV
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_rm_special_handler_003"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
remove_special_signal_handler
(
SIGSEGV
,
sigchain_special_sigsegv_handler1
);
remove_special_signal_handler
(
SIGSEGV
,
sigchain_special_sigsegv_handler2
);
raise
(
SIGSEGV
);
EXPECT_EQ
(
"sigchain_rm_special_handler_003"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_2
);
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_sigterm_handler
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_FALSE
(
"sigchain_rm_special_handler_004"
,
true
);
return
true
;
}
/**
* @tc.name : sigchain_rm_special_handler_004
* @tc.desc : the signal is not registered with the kernel, call remove_special_signal_handler to remove
* a special handler.
* @tc.level : Level 0
*/
static
void
sigchain_rm_special_handler_004
()
{
struct
signal_chain_action
sigsegv
=
{
.
sca_sigaction
=
sigchain_special_sigterm_handler
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGTERM
,
&
sigsegv
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGTERM
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_rm_special_handler_004"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
remove_special_signal_handler
(
SIGTERM
,
sigchain_special_sigterm_handler
);
raise
(
SIGTERM
);
EXPECT_EQ
(
"sigchain_rm_special_handler_004"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_2
);
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_64_handler
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
EXPECT_FALSE
(
"sigchain_rm_special_handler_005"
,
true
);
g_count
++
;
return
false
;
}
/**
* @brief the signal handler
*/
static
void
signal_64_handler
(
int
signo
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_rm_special_handler_005"
,
signo
,
SIGCHAIN_SIGNAL_64
);
}
/**
* @tc.name : sigchain_rm_special_handler_005
* @tc.desc : the signal is registered with the kernel(Using signal), call remove_special_signal_handler to remove
* a special handler.
* @tc.level : Level 0
*/
static
void
sigchain_rm_special_handler_005
()
{
signal
(
SIGCHAIN_SIGNAL_64
,
signal_64_handler
);
struct
signal_chain_action
sighup
=
{
.
sca_sigaction
=
sigchain_special_64_handler
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGCHAIN_SIGNAL_64
,
&
sighup
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGCHAIN_SIGNAL_64
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_rm_special_handler_005"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
remove_special_signal_handler
(
SIGCHAIN_SIGNAL_64
,
sigchain_special_64_handler
);
raise
(
SIGCHAIN_SIGNAL_64
);
EXPECT_EQ
(
"sigchain_rm_special_handler_005"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_3
);
}
/**
* @brief the special handler
*/
static
bool
sigchain_special_37_handler
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
g_count
++
;
EXPECT_FALSE
(
"sigchain_rm_special_handler_006"
,
true
);
return
false
;
}
/**
* @brief the signal handler
*/
static
void
signal_37_sigaction
(
int
signo
)
{
g_count
++
;
EXPECT_EQ
(
"sigchain_rm_special_handler_006"
,
signo
,
SIGCHAIN_SIGNAL_37
);
}
/**
* @tc.name : sigchain_rm_special_handler_006
* @tc.desc : the signal is registered with the kernel(Using sigaction), call remove_special_signal_handler
* to remove a special handler.
* @tc.level : Level 0
*/
static
void
sigchain_rm_special_handler_006
()
{
struct
sigaction
sigac
=
{
.
sa_handler
=
signal_37_sigaction
,
};
sigaction
(
SIGCHAIN_SIGNAL_37
,
&
sigac
,
NULL
);
struct
signal_chain_action
sig37
=
{
.
sca_sigaction
=
sigchain_special_37_handler
,
.
sca_mask
=
{},
.
sca_flags
=
0
,
};
add_special_signal_handler
(
SIGCHAIN_SIGNAL_37
,
&
sig37
);
if
(
get_sigchain_mask_enable
())
{
sigset_t
set
=
{
0
};
int
signo
[
SIGCHIAN_TEST_SIGNAL_NUM_1
]
=
{
SIGCHAIN_SIGNAL_37
};
SIGCHAIN_TEST_SET_MASK
(
set
,
"sigchain_rm_special_handler_006"
,
signo
,
SIGCHIAN_TEST_SIGNAL_NUM_1
);
}
remove_special_signal_handler
(
SIGCHAIN_SIGNAL_37
,
sigchain_special_37_handler
);
raise
(
SIGCHAIN_SIGNAL_37
);
EXPECT_EQ
(
"sigchain_rm_special_handler_006"
,
g_count
,
SIGCHIAN_TEST_SIGNAL_NUM_4
);
}
int
main
(
void
)
{
sigchain_rm_special_handler_001
();
sigchain_rm_special_handler_002
();
sigchain_rm_special_handler_003
();
sigchain_rm_special_handler_004
();
sigchain_rm_special_handler_005
();
sigchain_rm_special_handler_006
();
return
t_status
;
}
\ No newline at end of file
libc-test/src/functionalext/sigchain/test_src_functionalext_sigchain.gni
0 → 100644
浏览文件 @
0030a18d
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
functionalext_sigchain_list = [
"sigchain_add_special_handler",
"sigchain_rm_special_handler",
"sigchain_intercept_sigaction",
"sigchain_intercept_signal",
"sigchain_intercept_sigprocmask",
"sigchain_handler_call_order",
]
libc-test/src/functionalext/test_src_functionalext.gni
浏览文件 @
0030a18d
...
...
@@ -29,4 +29,5 @@ functionalext_list = [
"sched:functionalext_sched_test",
"unittest:functionalext_unittest_test",
"legacy:functionalext_legacy_test",
"sigchain:functionalext_sigchain_test",
]
libc-test/test_template.gni
浏览文件 @
0030a18d
...
...
@@ -233,6 +233,10 @@ template("test_unittest") {
}
}
}
if (target_dir == "functionalext/sigchain") {
include_dirs += [ "//${musl_base_dir}/include" ]
}
}
}
...
...
libc.map.txt
浏览文件 @
0030a18d
...
...
@@ -310,6 +310,7 @@
acoshl;
acosl;
addmntent;
add_special_signal_handler;
adjtime;
adjtimex;
aio_cancel;
...
...
@@ -1486,6 +1487,7 @@
remainderl;
remap_file_pages;
remove;
remove_special_signal_handler;
removexattr;
remque;
remquo;
...
...
musl_src.gni
浏览文件 @
0030a18d
...
...
@@ -1040,6 +1040,7 @@ musl_src_file = [
"src/signal/sigtimedwait.c",
"src/signal/sigwait.c",
"src/signal/sigwaitinfo.c",
"src/sigchain/sigchain.c",
"src/stat/__xstat.c",
"src/stat/chmod.c",
"src/stat/fchmod.c",
...
...
@@ -1974,6 +1975,7 @@ musl_inc_root_files = [
"include/setjmp.h",
"include/shadow.h",
"include/signal.h",
"include/sigchain.h",
"include/spawn.h",
"include/stdalign.h",
"include/stdarg.h",
...
...
@@ -2043,6 +2045,7 @@ musl_src_porting_file = [
"include/sys/socket.h",
"include/sys/sysinfo.h",
"include/signal.h",
"include/sigchain.h",
"include/sched.h",
"src/internal/dynlink.h",
"include/sys/tgkill.h",
...
...
@@ -2116,6 +2119,8 @@ musl_src_porting_file = [
"src/thread/pthread_create.c",
"src/sched/sched_cpualloc.c",
"src/signal/signal.c",
"src/signal/sigaction.c",
"src/signal/sigprocmask.c",
"include/langinfo.h",
"include/locale.h",
"src/hilog/hilog_adapter.c",
...
...
@@ -2147,6 +2152,7 @@ musl_src_porting_file = [
"src/process/x86_64/__vfork.s",
"src/linux/cache.c",
"src/sched/sched_getcpu.c",
"src/sigchain/sigchain.c",
]
musl_inc_hook_files = [
...
...
porting/linux/user/include/sigchain.h
0 → 100644
浏览文件 @
0030a18d
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _SIGCHAIN_H
#define _SIGCHAIN_H
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <signal.h>
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern
"C"
{
#endif
static
const
int
SIGCHAIN_ALLOW_NORETURN
=
0x1UL
;
/* The action of the sigchain. */
struct
signal_chain_action
{
bool
(
*
sca_sigaction
)(
int
,
siginfo_t
*
,
void
*
);
sigset_t
sca_mask
;
int
sca_flags
;
};
/* Mark the signal to the sigchain, add the special handler to the sigchain. */
void
add_special_signal_handler
(
int
signo
,
struct
signal_chain_action
*
sa
);
/* Remove the special the handler form the sigchain. */
void
remove_special_signal_handler
(
int
signo
,
bool
(
*
fn
)(
int
,
siginfo_t
*
,
void
*
));
#ifdef __cplusplus
}
#endif
#endif
\ No newline at end of file
porting/linux/user/src/sigchain/sigchain.c
0 → 100644
浏览文件 @
0030a18d
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sigchain.h>
#include <locale.h>
#include <pthread.h>
#include <errno.h>
#include <threads.h>
#include <hilog_adapter.h>
#include <stdlib.h>
extern
int
__libc_sigaction
(
int
sig
,
const
struct
sigaction
*
restrict
sa
,
struct
sigaction
*
restrict
old
);
#define SIG_CHAIN_KEY_VALUE_1 1
#define SIGNAL_CHAIN_SPECIAL_ACTION_MAX 2
#define SIGCHAIN_LOG_DOMAIN 0xD003F00
#define SIGCHAIN_LOG_TAG "SIGCHAIN"
#if (defined(OHOS_ENABLE_PARAMETER) || defined(ENABLE_MUSL_LOG))
#define SIGCHAIN_PRINT_ERROR(...) ((void)HiLogAdapterPrint(LOG_CORE, LOG_ERROR, \
SIGCHAIN_LOG_DOMAIN, SIGCHAIN_LOG_TAG, __VA_ARGS__))
#define SIGCHAIN_PRINT_INFO(...) ((void)HiLogAdapterPrint(LOG_CORE, LOG_INFO, \
SIGCHAIN_LOG_DOMAIN, SIGCHAIN_LOG_TAG, __VA_ARGS__))
#define SIGCHAIN_PRINT_DEBUG(...) ((void)HiLogAdapterPrint(LOG_CORE, LOG_DEBUG, \
SIGCHAIN_LOG_DOMAIN, SIGCHAIN_LOG_TAG, __VA_ARGS__))
#define SIGCHAIN_LOG_FATAL(...) ((void)HiLogAdapterPrint(LOG_CORE, LOG_FATAL, \
SIGCHAIN_LOG_DOMAIN, SIGCHAIN_LOG_TAG, __VA_ARGS__))
#else
#define SIGCHAIN_PRINT_ERROR(...)
#define SIGCHAIN_PRINT_INFO(...)
#define SIGCHAIN_PRINT_DEBUG(...)
#define SIGCHAIN_LOG_FATAL(...)
#endif
#define SIGCHAIN_PRINT_FATAL(...) do { \
SIGCHAIN_LOG_FATAL(__VA_ARGS__); \
abort(); \
} while(0)
struct
sc_signal_chain
{
bool
marked
;
struct
sigaction
sig_action
;
struct
signal_chain_action
sca_special_actions
[
SIGNAL_CHAIN_SPECIAL_ACTION_MAX
];
};
/* Signal chain set, from 0 to 63. */
static
struct
sc_signal_chain
sig_chains
[
_NSIG
-
1
];
/* static thread Keyword */
static
pthread_key_t
g_sigchain_key
;
/* This is once flag! */
static
once_flag
g_flag
=
ONCE_FLAG_INIT
;
/**
* @brief Create the thread key
* @retval void
*/
static
void
create_pthread_key
(
void
)
{
SIGCHAIN_PRINT_INFO
(
"%{public}s create the thread key!"
,
__func__
);
int
rc
=
pthread_key_create
(
&
g_sigchain_key
,
NULL
);
if
(
rc
!=
0
)
{
SIGCHAIN_PRINT_ERROR
(
"%{public}s failed to create sigchain pthread key, rc:%{public}d"
,
__func__
,
rc
);
}
}
/**
* @brief Get the key of the signal thread.
* @retval int32_t, the value of the sigchain key.
*/
static
pthread_key_t
get_handling_signal_key
()
{
call_once
(
&
g_flag
,
create_pthread_key
);
return
g_sigchain_key
;
}
/**
* @brief Get the value of the sigchain key
* @retval bool, true if set the value of the key,or false.
*/
static
bool
get_handling_signal
()
{
void
*
result
=
pthread_getspecific
(
get_handling_signal_key
());
return
result
==
NULL
?
false
:
true
;
}
/**
* @brief Set the value of the sigchain key
* @param[in] value, the value of the sigchain key
* @retval void.
*/
static
void
set_handling_signal
(
bool
value
)
{
pthread_setspecific
(
get_handling_signal_key
(),
(
void
*
)((
uintptr_t
)(
value
)));
}
/**
* @brief Judge whether the signal is marked
* @param[in] signo, the value of the signal.
* @retval true if the signal is marked, or false.
*/
bool
ismarked
(
int
signo
)
{
return
sig_chains
[
signo
-
1
].
marked
;
}
/**
* @brief This is a callback function, which is registered to the kernel
* @param[in] signo, the value of the signal.
* @param[in] siginfo, the information of the signal.
* @param[in] ucontext_raw, the context of the signal.
* @retval void
*/
static
void
signal_chain_handler
(
int
signo
,
siginfo_t
*
siginfo
,
void
*
ucontext_raw
)
{
SIGCHAIN_PRINT_DEBUG
(
"%{public}s signo: %{public}d"
,
__func__
,
signo
);
/* First call special handler. */
/* If a process crashes, the sigchain'll call the corresponding handler */
if
(
!
get_handling_signal
())
{
for
(
int
i
=
0
;
i
<
SIGNAL_CHAIN_SPECIAL_ACTION_MAX
;
i
++
)
{
if
(
sig_chains
[
signo
-
1
].
sca_special_actions
[
i
].
sca_sigaction
==
NULL
)
{
break
;
}
/* The special handler might not return. */
bool
noreturn
=
(
sig_chains
[
signo
-
1
].
sca_special_actions
[
i
].
sca_flags
&
SIGCHAIN_ALLOW_NORETURN
);
sigset_t
previous_mask
;
pthread_sigmask
(
SIG_SETMASK
,
&
sig_chains
[
signo
-
1
].
sca_special_actions
[
i
].
sca_mask
,
&
previous_mask
);
bool
previous_value
=
get_handling_signal
();
if
(
!
noreturn
)
{
set_handling_signal
(
true
);
}
if
(
sig_chains
[
signo
-
1
].
sca_special_actions
[
i
].
sca_sigaction
(
signo
,
siginfo
,
ucontext_raw
))
{
set_handling_signal
(
previous_value
);
return
;
}
pthread_sigmask
(
SIG_SETMASK
,
&
previous_mask
,
NULL
);
set_handling_signal
(
previous_value
);
}
}
/* Then Call the user's signal handler */
int
sa_flags
=
sig_chains
[
signo
-
1
].
sig_action
.
sa_flags
;
ucontext_t
*
ucontext
=
(
ucontext_t
*
)(
ucontext_raw
);
sigset_t
mask
;
sigorset
(
&
mask
,
&
ucontext
->
uc_sigmask
,
&
sig_chains
[
signo
-
1
].
sig_action
.
sa_mask
);
if
(
!
(
sa_flags
&
SA_NODEFER
))
{
sigaddset
(
&
mask
,
signo
);
}
pthread_sigmask
(
SIG_SETMASK
,
&
mask
,
NULL
);
if
((
sa_flags
&
SA_SIGINFO
))
{
sig_chains
[
signo
-
1
].
sig_action
.
sa_sigaction
(
signo
,
siginfo
,
ucontext_raw
);
}
else
{
if
(
sig_chains
[
signo
-
1
].
sig_action
.
sa_handler
==
SIG_IGN
)
{
return
;
}
else
if
(
sig_chains
[
signo
-
1
].
sig_action
.
sa_handler
==
SIG_DFL
)
{
SIGCHAIN_PRINT_INFO
(
"%{public}s exiting due to SIG_DFL handler for signal: %{public}d"
,
__func__
,
signo
);
}
else
{
sig_chains
[
signo
-
1
].
sig_action
.
sa_handler
(
signo
);
}
}
return
;
}
/**
* @brief Register the signal chain with the kernel if needed
* @param[in] signo, the value of the signal.
* @retval void
*/
static
void
sigchain_register
(
int
signo
)
{
SIGCHAIN_PRINT_INFO
(
"%{public}s signo: %{public}d"
,
__func__
,
signo
);
struct
sigaction
signal_action
=
{};
sigfillset
(
&
signal_action
.
sa_mask
);
signal_action
.
sa_sigaction
=
signal_chain_handler
;
signal_action
.
sa_flags
=
SA_RESTART
|
SA_SIGINFO
|
SA_ONSTACK
;
__libc_sigaction
(
signo
,
&
signal_action
,
&
sig_chains
[
signo
-
1
].
sig_action
);
}
/**
* @brief Mark the signal to the sigchain.
* @param[in] signo, the value of the signal.
* @retval void
*/
static
void
mark_signal_to_sigchain
(
int
signo
)
{
SIGCHAIN_PRINT_INFO
(
"%{public}s signo: %{public}d"
,
__func__
,
signo
);
if
(
!
sig_chains
[
signo
-
1
].
marked
)
{
sigchain_register
(
signo
);
sig_chains
[
signo
-
1
].
marked
=
true
;
}
}
/**
* @brief Set the action of the signal.
* @param[in] signo, the value of the signal.
* @param[in] new_sa, the new action of the signal.
* @retval void
*/
static
void
setaction
(
int
signo
,
const
struct
sigaction
*
restrict
new_sa
)
{
SIGCHAIN_PRINT_DEBUG
(
"%{public}s signo: %{public}d"
,
__func__
,
signo
);
sig_chains
[
signo
-
1
].
sig_action
=
*
new_sa
;
}
/**
* @brief Get the action of the signal.
* @param[in] signo, the value of the signal.
* @retval The current action of the signal
*/
static
struct
sigaction
getaction
(
int
signo
)
{
SIGCHAIN_PRINT_DEBUG
(
"%{public}s signo: %{public}d"
,
__func__
,
signo
);
return
sig_chains
[
signo
-
1
].
sig_action
;
}
/**
* @brief Add the special handler to the sigchain.
* @param[in] signo, the value of the signal.
* @param[in] sa, the action with special handler.
* @retval void
*/
void
add_special_handler
(
int
signo
,
struct
signal_chain_action
*
sa
)
{
SIGCHAIN_PRINT_INFO
(
"%{public}s signo: %{public}d"
,
__func__
,
signo
);
for
(
int
i
=
0
;
i
<
SIGNAL_CHAIN_SPECIAL_ACTION_MAX
;
i
++
)
{
if
(
sig_chains
[
signo
-
1
].
sca_special_actions
[
i
].
sca_sigaction
==
NULL
)
{
sig_chains
[
signo
-
1
].
sca_special_actions
[
i
]
=
*
sa
;
SIGCHAIN_PRINT_INFO
(
"%{public}s signo %{public}d is registered with special handler!"
,
__func__
,
signo
);
return
;
}
}
SIGCHAIN_PRINT_FATAL
(
"Add too many the special handlers!"
);
}
/**
* @brief Remove the special handler from the sigchain.
* @param[in] signo, the value of the signal.
* @param[in] fn, the special handler of the signal.
* @retval void
*/
void
rm_special_handler
(
int
signo
,
bool
(
*
fn
)(
int
,
siginfo_t
*
,
void
*
))
{
SIGCHAIN_PRINT_INFO
(
"%{public}s signo: %{public}d"
,
__func__
,
signo
);
int
len
=
SIGNAL_CHAIN_SPECIAL_ACTION_MAX
;
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
if
(
sig_chains
[
signo
-
1
].
sca_special_actions
[
i
].
sca_sigaction
==
fn
)
{
for
(
int
j
=
i
;
j
<
len
-
1
;
++
j
)
{
sig_chains
[
signo
-
1
].
sca_special_actions
[
j
]
=
sig_chains
[
signo
-
1
].
sca_special_actions
[
j
+
1
];
}
sig_chains
[
signo
-
1
].
sca_special_actions
[
len
-
1
].
sca_sigaction
=
NULL
;
return
;
}
}
SIGCHAIN_PRINT_FATAL
(
"%{public}s failed to remove the special handler!. signo: %{public}d"
,
__func__
,
signo
);
}
/**
* @brief This is an external interface,
* Mark the signal to sigchain ,add the special handler to the sigchain.
* @param[in] signo, the value of the signal.
* @param[in] sa, the action with special handler.
* @retval void
*/
void
add_special_signal_handler
(
int
signo
,
struct
signal_chain_action
*
sa
)
{
SIGCHAIN_PRINT_INFO
(
"%{public}s signo: %{public}d"
,
__func__
,
signo
);
if
(
signo
<=
0
||
signo
>=
_NSIG
)
{
SIGCHAIN_PRINT_FATAL
(
"%{public}s Invalid signal %{public}d"
,
__func__
,
signo
);
return
;
}
// Add the special hander to the sigchain
add_special_handler
(
signo
,
sa
);
mark_signal_to_sigchain
(
signo
);
}
/**
* @brief This is an external interface, remove the special handler from the sigchain.
* @param[in] signo, the value of the signal.
* @param[in] fn, the special handler of the signal.
* @retval void
*/
void
remove_special_signal_handler
(
int
signo
,
bool
(
*
fn
)(
int
,
siginfo_t
*
,
void
*
))
{
SIGCHAIN_PRINT_INFO
(
"%{public}s signo: %{public}d"
,
__func__
,
signo
);
if
(
signo
<=
0
||
signo
>=
_NSIG
)
{
SIGCHAIN_PRINT_FATAL
(
"%{public}s Invalid signal %{public}d"
,
__func__
,
signo
);
return
;
}
// remove the special handler from the sigchain.
rm_special_handler
(
signo
,
fn
);
}
/**
* @brief Intercept the signal and sigaction.
* @param[in] signo, the value of the signal.
* @param[in] sa, the new action with the signal handler.
* @param[out] old, the old action with the signal handler.
* @retval true if the signal if intercepted, or false.
*/
bool
intercept_sigaction
(
int
signo
,
const
struct
sigaction
*
restrict
sa
,
struct
sigaction
*
restrict
old
)
{
SIGCHAIN_PRINT_DEBUG
(
"%{public}s signo: %{public}d"
,
__func__
,
signo
);
if
(
signo
<=
0
||
signo
>=
_NSIG
)
{
SIGCHAIN_PRINT_ERROR
(
"%{public}s Invalid signal %{public}d"
,
__func__
,
signo
);
return
false
;
}
if
(
ismarked
(
signo
))
{
struct
sigaction
saved_action
=
getaction
(
signo
);
if
(
sa
!=
NULL
)
{
setaction
(
signo
,
sa
);
}
if
(
old
!=
NULL
)
{
*
old
=
saved_action
;
}
return
true
;
}
return
false
;
}
/**
* @brief Intercept the sigprocmask.
* @param[in] how, the value of the mask operation .
* @param[out] set, the value of the sigset.
* @retval void.
*/
void
intercept_sigprocmask
(
int
how
,
sigset_t
*
restrict
set
)
{
SIGCHAIN_PRINT_DEBUG
(
"%{public}s how: %{public}d"
,
__func__
,
how
);
// Forward directly to the pthread_sigmask When this sigchain is handling a signal.
if
(
get_handling_signal
())
{
return
;
}
sigset_t
tmpset
;
if
(
set
!=
NULL
)
{
tmpset
=
*
set
;
if
(
how
==
SIG_BLOCK
||
how
==
SIG_SETMASK
)
{
for
(
int
i
=
1
;
i
<
_NSIG
;
++
i
)
{
if
(
ismarked
(
i
)
&&
sigismember
(
&
tmpset
,
i
))
{
sigdelset
(
&
tmpset
,
i
);
}
}
}
*
set
=
tmpset
;
}
return
;
}
porting/linux/user/src/signal/sigaction.c
0 → 100644
浏览文件 @
0030a18d
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>
#include "syscall.h"
#include "pthread_impl.h"
#include "libc.h"
#include "lock.h"
#include "ksigaction.h"
extern
bool
intercept_sigaction
(
int
signo
,
const
struct
sigaction
*
restrict
sa
,
struct
sigaction
*
restrict
old
);
static
volatile
int
dummy_lock
[
1
]
=
{
0
};
extern
hidden
volatile
int
__abort_lock
[
1
];
weak_alias
(
dummy_lock
,
__abort_lock
);
static
int
unmask_done
;
static
unsigned
long
handler_set
[
_NSIG
/
(
8
*
sizeof
(
long
))];
void
__get_handler_set
(
sigset_t
*
set
)
{
memcpy
(
set
,
handler_set
,
sizeof
handler_set
);
}
volatile
int
__eintr_valid_flag
;
int
__libc_sigaction
(
int
sig
,
const
struct
sigaction
*
restrict
sa
,
struct
sigaction
*
restrict
old
)
{
struct
k_sigaction
ksa
,
ksa_old
;
unsigned
long
set
[
_NSIG
/
(
8
*
sizeof
(
long
))];
if
(
sa
)
{
if
((
uintptr_t
)
sa
->
sa_handler
>
1UL
)
{
a_or_l
(
handler_set
+
(
sig
-
1
)
/
(
8
*
sizeof
(
long
)),
1UL
<<
(
sig
-
1
)
%
(
8
*
sizeof
(
long
)));
/* If pthread_create has not yet been called,
* implementation-internal signals might not
* yet have been unblocked. They must be
* unblocked before any signal handler is
* installed, so that an application cannot
* receive an illegal sigset_t (with them
* blocked) as part of the ucontext_t passed
* to the signal handler. */
if
(
!
libc
.
threaded
&&
!
unmask_done
)
{
__syscall
(
SYS_rt_sigprocmask
,
SIG_UNBLOCK
,
SIGPT_SET
,
0
,
_NSIG
/
8
);
unmask_done
=
1
;
}
if
(
!
(
sa
->
sa_flags
&
SA_RESTART
))
{
a_store
(
&
__eintr_valid_flag
,
1
);
}
}
/* Changing the disposition of SIGABRT to anything but
* SIG_DFL requires a lock, so that it cannot be changed
* while abort is terminating the process after simply
* calling raise(SIGABRT) failed to do so. */
if
(
sa
->
sa_handler
!=
SIG_DFL
&&
sig
==
SIGABRT
)
{
__block_all_sigs
(
&
set
);
LOCK
(
__abort_lock
);
}
ksa
.
handler
=
sa
->
sa_handler
;
ksa
.
flags
=
sa
->
sa_flags
|
SA_RESTORER
;
ksa
.
restorer
=
(
sa
->
sa_flags
&
SA_SIGINFO
)
?
__restore_rt
:
__restore
;
memcpy
(
&
ksa
.
mask
,
&
sa
->
sa_mask
,
_NSIG
/
8
);
}
int
r
=
__syscall
(
SYS_rt_sigaction
,
sig
,
sa
?&
ksa
:
0
,
old
?&
ksa_old
:
0
,
_NSIG
/
8
);
if
(
sig
==
SIGABRT
&&
sa
&&
sa
->
sa_handler
!=
SIG_DFL
)
{
UNLOCK
(
__abort_lock
);
__restore_sigs
(
&
set
);
}
if
(
old
&&
!
r
)
{
old
->
sa_handler
=
ksa_old
.
handler
;
old
->
sa_flags
=
ksa_old
.
flags
;
memcpy
(
&
old
->
sa_mask
,
&
ksa_old
.
mask
,
_NSIG
/
8
);
}
return
__syscall_ret
(
r
);
}
int
__sigaction
(
int
sig
,
const
struct
sigaction
*
restrict
sa
,
struct
sigaction
*
restrict
old
)
{
if
(
sig
-
32U
<
3
||
sig
-
1U
>=
_NSIG
-
1
)
{
errno
=
EINVAL
;
return
-
1
;
}
if
(
intercept_sigaction
(
sig
,
sa
,
old
))
{
return
0
;
}
return
__libc_sigaction
(
sig
,
sa
,
old
);
}
weak_alias
(
__sigaction
,
sigaction
);
porting/linux/user/src/signal/sigprocmask.c
0 → 100644
浏览文件 @
0030a18d
#include <signal.h>
#include <errno.h>
#include <sigchain.h>
#include <stddef.h>
#include <hilog_adapter.h>
#include <string.h>
#ifdef OHOS_ENABLE_PARAMETER
#include "sys_param.h"
#endif
extern
void
intercept_sigprocmask
(
int
how
,
sigset_t
*
restrict
set
);
static
const
char
*
param_name
=
"musl.sigchain.procmask"
;
bool
get_sigchain_mask_enable
()
{
#ifdef OHOS_ENABLE_PARAMETER
static
CachedHandle
sigchain_procmask_handle
=
NULL
;
if
(
sigchain_procmask_handle
==
NULL
)
{
sigchain_procmask_handle
=
CachedParameterCreate
(
param_name
,
"false"
);
}
char
*
param_value
=
CachedParameterGet
(
sigchain_procmask_handle
);
if
(
param_value
!=
NULL
)
{
if
(
strcmp
(
param_value
,
"true"
)
==
0
)
{
return
true
;
}
}
#endif
return
false
;
}
int
sigprocmask
(
int
how
,
const
sigset_t
*
restrict
set
,
sigset_t
*
restrict
old
)
{
int
r
=
0
;
if
(
set
&&
get_sigchain_mask_enable
())
{
sigset_t
tmpset
=
*
set
;
intercept_sigprocmask
(
how
,
&
tmpset
);
const
sigset_t
*
new_set_ptr
=
&
tmpset
;
r
=
pthread_sigmask
(
how
,
new_set_ptr
,
old
);
}
else
{
r
=
pthread_sigmask
(
how
,
set
,
old
);
}
if
(
!
r
)
return
r
;
errno
=
r
;
return
-
1
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录