Author: jilles
Date: Mon Dec 26 17:26:25 2016
New Revision: 310610
URL: https://svnweb.freebsd.org/changeset/base/310610

Log:
  MFC r309957: Add tests for reaper receiving SIGCHLD (r309886).
  
  PR:           213928

Modified:
  stable/10/tests/sys/kern/reaper.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/tests/sys/kern/reaper.c
==============================================================================
--- stable/10/tests/sys/kern/reaper.c   Mon Dec 26 17:23:09 2016        
(r310609)
+++ stable/10/tests/sys/kern/reaper.c   Mon Dec 26 17:26:25 2016        
(r310610)
@@ -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
        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);
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to