diff --git a/libc-test/src/functionalext/sigchain/sigchain_intercept_sigaction.c b/libc-test/src/functionalext/sigchain/sigchain_intercept_sigaction.c index efc78aa3ea7e4374c522aaacbb94a13feef22143..43a2ac53e03977df10343403aa0dc44c52ce9f77 100644 --- a/libc-test/src/functionalext/sigchain/sigchain_intercept_sigaction.c +++ b/libc-test/src/functionalext/sigchain/sigchain_intercept_sigaction.c @@ -17,11 +17,43 @@ #include #include #include +#include #include "test.h" #include "functionalext.h" #include "sigchain_util.h" static int g_count = 0; +#define ZERO (0) +#define VAL_INT (1024) + +void wait_until_sigabrt(void) +{ + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGABRT); + // 设置超时结构,设置超时为 0.5 秒 + struct timespec timeout; + timeout.tv_sec = 0; // 秒部分为 0 + timeout.tv_nsec = 500000000; // 纳秒部分为 500000000,即 0.5 秒 + (void)sigtimedwait(&set, NULL, &timeout); +} + +static void sigaction_abort(int signo, siginfo_t *info, void *context) +{ + EXPECT_EQ("sigchain_intercept_sigaction_000 check sival_int failed", info->si_value.sival_int, VAL_INT); + g_count++; + EXPECT_EQ("sigchain_intercept_sigaction_001", signo, SIGABRT); +} + +/** + * @brief the SIGABRT handler + */ +static void signal_handler_sigabrt(int signo) +{ + g_count++; + EXPECT_EQ("sigchain_intercept_sigaction_002", signo, SIGABRT); +} + /** * @brief the special handler */ @@ -152,10 +184,69 @@ static void sigchain_intercept_sigaction_003() EXPECT_EQ("sigchain_intercept_sigaction_003", g_count, SIGCHIAN_TEST_SIGNAL_NUM_1); } +/** + * @tc.name : sigchain_intercept_sigaction_sigabort + * @tc.desc : Test whether the user manually sets sa_sigaction for the SIGABRT signal to execute normally. + * Test whether the user manually sets sa_handler for the SIGABRT signal to execute normally. + * @tc.level : Level 0 + */ +static void sigchain_intercept_sigaction_sigabort(void) +{ + // 解除signal6的信号屏蔽 + sigset_t remove_signal6_mask; + sigemptyset(&remove_signal6_mask); + sigaddset(&remove_signal6_mask, SIGABRT); + if (sigprocmask(SIG_UNBLOCK, &remove_signal6_mask, NULL) == -1) { + t_error("sigprocmask remove signal 6 failed errno=%d\n", errno); + } + g_count = 0; + struct sigaction action = { + .sa_sigaction = sigaction_abort, + .sa_flags = SA_SIGINFO, + }; + int result = sigaction(SIGABRT, &action, NULL); + if (result != ZERO) { + t_error("sigchain_intercept_sigaction_sigabort sigaction 1 failed, errno=%d\n", errno); + } + // 1. 创建 sigval 结构体并设置附加数据,校验sa_sigaction场景是否有效,并校验参数是否已经带上 + union sigval value; + value.sival_int = VAL_INT; + result = sigqueue(getpid(), SIGABRT, value); + if (result != ZERO) { + t_error("sigchain_intercept_sigaction_sigabort sigqueue failed errno=%d\n", errno); + return; + } + wait_until_sigabrt(); + EXPECT_EQ("sigchain_intercept_sigaction_sigabort", g_count, SIGCHIAN_TEST_SIGNAL_NUM_1); + + // 2. 清理状态 + g_count = 0; + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_DFL; + sigemptyset(&action.sa_mask); + action.sa_flags = 0; + result = sigaction(SIGABRT, &action, NULL); + if (result != ZERO) { + t_error("sigchain_intercept_sigaction_sigabort sigaction 2 failed, errno=%d\n", errno); + } + // 3. 使用sa_handler的方式处理sigabrt,并判断是否走到了信号处理函数 + action.sa_handler = signal_handler_sigabrt; + + action.sa_flags = SA_RESTART; + result = sigaction(SIGABRT, &action, NULL); + if (result != ZERO) { + t_error("sigchain_intercept_sigaction_sigabort sigaction 3 failed, errno=%d\n", errno); + } + (void)raise(SIGABRT); + wait_until_sigabrt(); + EXPECT_EQ("sigchain_intercept_sigaction_sigabort", g_count, SIGCHIAN_TEST_SIGNAL_NUM_1); +} + int main(void) { sigchain_intercept_sigaction_001(); sigchain_intercept_sigaction_002(); sigchain_intercept_sigaction_003(); + sigchain_intercept_sigaction_sigabort(); return t_status; } \ No newline at end of file