mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 06:14:58 +00:00
Tests: Add tests for sigwait/sigwaitinfo/sigtimedwait
This commit is contained in:
parent
656b1dd6be
commit
8d3faecd9b
2 changed files with 180 additions and 0 deletions
|
@ -42,6 +42,7 @@ set(LIBTEST_BASED_SOURCES
|
|||
TestProcFS.cpp
|
||||
TestProcFSWrite.cpp
|
||||
TestSigAltStack.cpp
|
||||
TestSigWait.cpp
|
||||
)
|
||||
|
||||
foreach(libtest_source IN LISTS LIBTEST_BASED_SOURCES)
|
||||
|
|
179
Tests/Kernel/TestSigWait.cpp
Normal file
179
Tests/Kernel/TestSigWait.cpp
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibTest/TestCase.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
TEST_CASE(sigwait)
|
||||
{
|
||||
sigset_t mask;
|
||||
|
||||
int rc = sigemptyset(&mask);
|
||||
EXPECT_EQ(rc, 0);
|
||||
rc = sigaddset(&mask, SIGUSR1);
|
||||
EXPECT_EQ(rc, 0);
|
||||
rc = sigprocmask(SIG_BLOCK, &mask, nullptr);
|
||||
EXPECT_EQ(rc, 0);
|
||||
|
||||
int child_pid = fork();
|
||||
EXPECT(child_pid >= 0);
|
||||
if (child_pid == 0) {
|
||||
sleep(1);
|
||||
kill(getppid(), SIGUSR1);
|
||||
exit(EXIT_SUCCESS);
|
||||
} else {
|
||||
int sig;
|
||||
rc = sigwait(&mask, &sig);
|
||||
EXPECT_EQ(rc, 0);
|
||||
EXPECT_EQ(sig, SIGUSR1);
|
||||
}
|
||||
|
||||
// cancel pending signal
|
||||
struct sigaction act_ignore = { { SIG_IGN }, 0, 0 };
|
||||
rc = sigaction(SIGUSR1, &act_ignore, nullptr);
|
||||
EXPECT_EQ(rc, 0);
|
||||
rc = sigprocmask(SIG_UNBLOCK, &mask, nullptr);
|
||||
EXPECT_EQ(rc, 0);
|
||||
struct sigaction act_default = { { SIG_DFL }, 0, 0 };
|
||||
rc = sigaction(SIGUSR1, &act_default, nullptr);
|
||||
EXPECT_EQ(rc, 0);
|
||||
sigset_t pending;
|
||||
rc = sigpending(&pending);
|
||||
EXPECT_EQ(rc, 0);
|
||||
EXPECT_EQ(pending, 0u);
|
||||
}
|
||||
|
||||
TEST_CASE(sigwaitinfo)
|
||||
{
|
||||
sigset_t mask;
|
||||
|
||||
int rc = sigemptyset(&mask);
|
||||
EXPECT_EQ(rc, 0);
|
||||
rc = sigaddset(&mask, SIGUSR1);
|
||||
EXPECT_EQ(rc, 0);
|
||||
rc = sigprocmask(SIG_BLOCK, &mask, nullptr);
|
||||
EXPECT_EQ(rc, 0);
|
||||
|
||||
int child_pid = fork();
|
||||
EXPECT(child_pid >= 0);
|
||||
if (child_pid == 0) {
|
||||
sleep(1);
|
||||
kill(getppid(), SIGUSR1);
|
||||
exit(EXIT_SUCCESS);
|
||||
} else {
|
||||
siginfo_t info;
|
||||
rc = sigwaitinfo(&mask, &info);
|
||||
EXPECT_EQ(rc, SIGUSR1);
|
||||
EXPECT_EQ(info.si_signo, SIGUSR1);
|
||||
}
|
||||
|
||||
// cancel pending signal
|
||||
struct sigaction act_ignore = { { SIG_IGN }, 0, 0 };
|
||||
rc = sigaction(SIGUSR1, &act_ignore, nullptr);
|
||||
EXPECT_EQ(rc, 0);
|
||||
rc = sigprocmask(SIG_UNBLOCK, &mask, nullptr);
|
||||
EXPECT_EQ(rc, 0);
|
||||
struct sigaction act_default = { { SIG_DFL }, 0, 0 };
|
||||
rc = sigaction(SIGUSR1, &act_default, nullptr);
|
||||
EXPECT_EQ(rc, 0);
|
||||
sigset_t pending;
|
||||
rc = sigpending(&pending);
|
||||
EXPECT_EQ(rc, 0);
|
||||
EXPECT_EQ(pending, 0u);
|
||||
}
|
||||
|
||||
TEST_CASE(sigtimedwait_normal)
|
||||
{
|
||||
sigset_t mask;
|
||||
|
||||
int rc = sigemptyset(&mask);
|
||||
EXPECT_EQ(rc, 0);
|
||||
rc = sigaddset(&mask, SIGUSR1);
|
||||
EXPECT_EQ(rc, 0);
|
||||
rc = sigprocmask(SIG_BLOCK, &mask, nullptr);
|
||||
EXPECT_EQ(rc, 0);
|
||||
|
||||
int child_pid = fork();
|
||||
EXPECT(child_pid >= 0);
|
||||
if (child_pid == 0) {
|
||||
sleep(1);
|
||||
kill(getppid(), SIGUSR1);
|
||||
exit(EXIT_SUCCESS);
|
||||
} else {
|
||||
siginfo_t info;
|
||||
struct timespec timeout = { .tv_sec = 2, .tv_nsec = 0 };
|
||||
rc = sigtimedwait(&mask, &info, &timeout);
|
||||
EXPECT_EQ(rc, SIGUSR1);
|
||||
EXPECT_EQ(info.si_signo, SIGUSR1);
|
||||
}
|
||||
|
||||
// cancel pending signal
|
||||
struct sigaction act_ignore = { { SIG_IGN }, 0, 0 };
|
||||
rc = sigaction(SIGUSR1, &act_ignore, nullptr);
|
||||
EXPECT_EQ(rc, 0);
|
||||
rc = sigprocmask(SIG_UNBLOCK, &mask, nullptr);
|
||||
EXPECT_EQ(rc, 0);
|
||||
struct sigaction act_default = { { SIG_DFL }, 0, 0 };
|
||||
rc = sigaction(SIGUSR1, &act_default, nullptr);
|
||||
EXPECT_EQ(rc, 0);
|
||||
sigset_t pending;
|
||||
rc = sigpending(&pending);
|
||||
EXPECT_EQ(rc, 0);
|
||||
EXPECT_EQ(pending, 0u);
|
||||
}
|
||||
|
||||
TEST_CASE(sigtimedwait_poll)
|
||||
{
|
||||
sigset_t mask;
|
||||
|
||||
int rc = sigemptyset(&mask);
|
||||
EXPECT_EQ(rc, 0);
|
||||
rc = sigaddset(&mask, SIGUSR1);
|
||||
EXPECT_EQ(rc, 0);
|
||||
rc = sigprocmask(SIG_BLOCK, &mask, nullptr);
|
||||
EXPECT_EQ(rc, 0);
|
||||
|
||||
struct timespec poll_timeout = { .tv_sec = 0, .tv_nsec = 0 };
|
||||
rc = sigtimedwait(&mask, nullptr, &poll_timeout);
|
||||
EXPECT_EQ(rc, -1);
|
||||
EXPECT_EQ(errno, EAGAIN);
|
||||
|
||||
kill(getpid(), SIGUSR1);
|
||||
|
||||
siginfo_t info;
|
||||
rc = sigtimedwait(&mask, &info, &poll_timeout);
|
||||
EXPECT_EQ(rc, SIGUSR1);
|
||||
EXPECT_EQ(info.si_signo, SIGUSR1);
|
||||
|
||||
// cancel pending signal
|
||||
struct sigaction act_ignore = { { SIG_IGN }, 0, 0 };
|
||||
rc = sigaction(SIGUSR1, &act_ignore, nullptr);
|
||||
EXPECT_EQ(rc, 0);
|
||||
rc = sigprocmask(SIG_UNBLOCK, &mask, nullptr);
|
||||
EXPECT_EQ(rc, 0);
|
||||
struct sigaction act_default = { { SIG_DFL }, 0, 0 };
|
||||
rc = sigaction(SIGUSR1, &act_default, nullptr);
|
||||
EXPECT_EQ(rc, 0);
|
||||
sigset_t pending;
|
||||
rc = sigpending(&pending);
|
||||
EXPECT_EQ(rc, 0);
|
||||
EXPECT_EQ(pending, 0u);
|
||||
}
|
||||
|
||||
TEST_CASE(sigtimedwait_timeout)
|
||||
{
|
||||
sigset_t mask;
|
||||
int rc = sigemptyset(&mask);
|
||||
EXPECT_EQ(rc, 0);
|
||||
rc = sigaddset(&mask, SIGUSR1);
|
||||
EXPECT_EQ(rc, 0);
|
||||
struct timespec timeout = { .tv_sec = 1, .tv_nsec = 0 };
|
||||
rc = sigtimedwait(&mask, nullptr, &timeout);
|
||||
EXPECT_EQ(rc, -1);
|
||||
EXPECT_EQ(errno, EAGAIN);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue