Add tests for reaper receiving SIGCHLD (r309886).
PR: 213928 MFC after: 2 weeks
This commit is contained in:
parent
6c26775c2f
commit
fe56b17710
@ -35,6 +35,11 @@ __FBSDID("$FreeBSD$");
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void
|
||||
dummy_sighandler(int sig __unused, siginfo_t *info __unused, void *ctx __unused)
|
||||
{
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(reaper_wait_child_first);
|
||||
ATF_TC_BODY(reaper_wait_child_first, tc)
|
||||
{
|
||||
@ -129,6 +134,161 @@ ATF_TC_BODY(reaper_wait_grandchild_first, tc)
|
||||
ATF_CHECK_EQ(2, r);
|
||||
}
|
||||
|
||||
ATF_TC(reaper_sigchld_child_first);
|
||||
ATF_TC_HEAD(reaper_sigchld_child_first, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "timeout", "2");
|
||||
}
|
||||
ATF_TC_BODY(reaper_sigchld_child_first, tc)
|
||||
{
|
||||
struct sigaction act;
|
||||
sigset_t mask;
|
||||
siginfo_t info;
|
||||
pid_t parent, child, grandchild, pid;
|
||||
int r;
|
||||
int pip[2];
|
||||
|
||||
/* Be paranoid. */
|
||||
pid = waitpid(-1, NULL, WNOHANG);
|
||||
ATF_REQUIRE(pid == -1 && errno == ECHILD);
|
||||
|
||||
act.sa_sigaction = dummy_sighandler;
|
||||
act.sa_flags = SA_SIGINFO | SA_RESTART;
|
||||
r = sigemptyset(&act.sa_mask);
|
||||
ATF_REQUIRE_EQ(0, r);
|
||||
r = sigaction(SIGCHLD, &act, NULL);
|
||||
ATF_REQUIRE_EQ(0, r);
|
||||
|
||||
r = sigemptyset(&mask);
|
||||
ATF_REQUIRE_EQ(0, r);
|
||||
r = sigaddset(&mask, SIGCHLD);
|
||||
ATF_REQUIRE_EQ(0, r);
|
||||
r = sigprocmask(SIG_BLOCK, &mask, NULL);
|
||||
ATF_REQUIRE_EQ(0, r);
|
||||
|
||||
parent = getpid();
|
||||
r = procctl(P_PID, parent, PROC_REAP_ACQUIRE, NULL);
|
||||
ATF_REQUIRE_EQ(0, r);
|
||||
|
||||
r = pipe(pip);
|
||||
ATF_REQUIRE_EQ(0, r);
|
||||
|
||||
child = fork();
|
||||
ATF_REQUIRE(child != -1);
|
||||
if (child == 0) {
|
||||
if (close(pip[1]) != 0)
|
||||
_exit(100);
|
||||
grandchild = fork();
|
||||
if (grandchild == -1)
|
||||
_exit(101);
|
||||
else if (grandchild == 0) {
|
||||
if (read(pip[0], &(uint8_t){ 0 }, 1) != 0)
|
||||
_exit(102);
|
||||
if (getppid() != parent)
|
||||
_exit(103);
|
||||
_exit(2);
|
||||
} else
|
||||
_exit(3);
|
||||
}
|
||||
|
||||
r = sigwaitinfo(&mask, &info);
|
||||
ATF_REQUIRE_EQ(SIGCHLD, r);
|
||||
ATF_CHECK_EQ(SIGCHLD, info.si_signo);
|
||||
ATF_CHECK_EQ(CLD_EXITED, info.si_code);
|
||||
ATF_CHECK_EQ(3, info.si_status);
|
||||
ATF_CHECK_EQ(child, info.si_pid);
|
||||
|
||||
pid = waitpid(child, NULL, 0);
|
||||
ATF_REQUIRE_EQ(child, pid);
|
||||
|
||||
r = close(pip[1]);
|
||||
ATF_REQUIRE_EQ(0, r);
|
||||
|
||||
r = sigwaitinfo(&mask, &info);
|
||||
ATF_REQUIRE_EQ(SIGCHLD, r);
|
||||
ATF_CHECK_EQ(SIGCHLD, info.si_signo);
|
||||
ATF_CHECK_EQ(CLD_EXITED, info.si_code);
|
||||
ATF_CHECK_EQ(2, info.si_status);
|
||||
grandchild = info.si_pid;
|
||||
ATF_REQUIRE(grandchild > 0);
|
||||
ATF_REQUIRE(grandchild != parent);
|
||||
ATF_REQUIRE(grandchild != child);
|
||||
|
||||
pid = waitpid(-1, NULL, 0);
|
||||
ATF_REQUIRE_EQ(grandchild, pid);
|
||||
|
||||
r = close(pip[0]);
|
||||
ATF_REQUIRE_EQ(0, r);
|
||||
}
|
||||
|
||||
ATF_TC(reaper_sigchld_grandchild_first);
|
||||
ATF_TC_HEAD(reaper_sigchld_grandchild_first, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "timeout", "2");
|
||||
}
|
||||
ATF_TC_BODY(reaper_sigchld_grandchild_first, tc)
|
||||
{
|
||||
struct sigaction act;
|
||||
sigset_t mask;
|
||||
siginfo_t info;
|
||||
pid_t parent, child, grandchild, pid;
|
||||
int r;
|
||||
|
||||
/* Be paranoid. */
|
||||
pid = waitpid(-1, NULL, WNOHANG);
|
||||
ATF_REQUIRE(pid == -1 && errno == ECHILD);
|
||||
|
||||
act.sa_sigaction = dummy_sighandler;
|
||||
act.sa_flags = SA_SIGINFO | SA_RESTART;
|
||||
r = sigemptyset(&act.sa_mask);
|
||||
ATF_REQUIRE_EQ(0, r);
|
||||
r = sigaction(SIGCHLD, &act, NULL);
|
||||
ATF_REQUIRE_EQ(0, r);
|
||||
|
||||
r = sigemptyset(&mask);
|
||||
ATF_REQUIRE_EQ(0, r);
|
||||
r = sigaddset(&mask, SIGCHLD);
|
||||
ATF_REQUIRE_EQ(0, r);
|
||||
r = sigprocmask(SIG_BLOCK, &mask, NULL);
|
||||
ATF_REQUIRE_EQ(0, r);
|
||||
|
||||
parent = getpid();
|
||||
r = procctl(P_PID, parent, PROC_REAP_ACQUIRE, NULL);
|
||||
ATF_REQUIRE_EQ(0, r);
|
||||
|
||||
child = fork();
|
||||
ATF_REQUIRE(child != -1);
|
||||
if (child == 0) {
|
||||
grandchild = fork();
|
||||
if (grandchild == -1)
|
||||
_exit(101);
|
||||
else if (grandchild == 0)
|
||||
_exit(2);
|
||||
else {
|
||||
if (waitid(P_PID, grandchild, NULL,
|
||||
WNOWAIT | WEXITED) != 0)
|
||||
_exit(102);
|
||||
_exit(3);
|
||||
}
|
||||
}
|
||||
|
||||
pid = waitpid(child, NULL, 0);
|
||||
ATF_REQUIRE_EQ(child, pid);
|
||||
|
||||
r = sigwaitinfo(&mask, &info);
|
||||
ATF_REQUIRE_EQ(SIGCHLD, r);
|
||||
ATF_CHECK_EQ(SIGCHLD, info.si_signo);
|
||||
ATF_CHECK_EQ(CLD_EXITED, info.si_code);
|
||||
ATF_CHECK_EQ(2, info.si_status);
|
||||
grandchild = info.si_pid;
|
||||
ATF_REQUIRE(grandchild > 0);
|
||||
ATF_REQUIRE(grandchild != parent);
|
||||
ATF_REQUIRE(grandchild != child);
|
||||
|
||||
pid = waitpid(-1, NULL, 0);
|
||||
ATF_REQUIRE_EQ(grandchild, pid);
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(reaper_status);
|
||||
ATF_TC_BODY(reaper_status, tc)
|
||||
{
|
||||
@ -484,6 +644,8 @@ ATF_TP_ADD_TCS(tp)
|
||||
|
||||
ATF_TP_ADD_TC(tp, reaper_wait_child_first);
|
||||
ATF_TP_ADD_TC(tp, reaper_wait_grandchild_first);
|
||||
ATF_TP_ADD_TC(tp, reaper_sigchld_child_first);
|
||||
ATF_TP_ADD_TC(tp, reaper_sigchld_grandchild_first);
|
||||
ATF_TP_ADD_TC(tp, reaper_status);
|
||||
ATF_TP_ADD_TC(tp, reaper_getpids);
|
||||
ATF_TP_ADD_TC(tp, reaper_kill_badsig);
|
||||
|
Loading…
Reference in New Issue
Block a user