Home | History | Annotate | Line # | Download | only in sys
      1  1.8  riastrad /*	$NetBSD: t_ptrace_fork_wait.h,v 1.8 2025/05/02 02:24:32 riastradh Exp $	*/
      2  1.1     kamil 
      3  1.1     kamil /*-
      4  1.1     kamil  * Copyright (c) 2016, 2017, 2018, 2020 The NetBSD Foundation, Inc.
      5  1.1     kamil  * All rights reserved.
      6  1.1     kamil  *
      7  1.1     kamil  * Redistribution and use in source and binary forms, with or without
      8  1.1     kamil  * modification, are permitted provided that the following conditions
      9  1.1     kamil  * are met:
     10  1.1     kamil  * 1. Redistributions of source code must retain the above copyright
     11  1.1     kamil  *    notice, this list of conditions and the following disclaimer.
     12  1.1     kamil  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1     kamil  *    notice, this list of conditions and the following disclaimer in the
     14  1.1     kamil  *    documentation and/or other materials provided with the distribution.
     15  1.1     kamil  *
     16  1.1     kamil  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17  1.1     kamil  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18  1.1     kamil  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  1.1     kamil  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20  1.1     kamil  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  1.1     kamil  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  1.1     kamil  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23  1.1     kamil  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24  1.1     kamil  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  1.1     kamil  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  1.1     kamil  * POSSIBILITY OF SUCH DAMAGE.
     27  1.1     kamil  */
     28  1.1     kamil 
     29  1.1     kamil static void
     30  1.1     kamil fork_body(const char *fn, bool trackspawn, bool trackfork, bool trackvfork,
     31  1.7     kamil     bool trackvforkdone, bool newpgrp)
     32  1.1     kamil {
     33  1.1     kamil 	const int exitval = 5;
     34  1.1     kamil 	const int exitval2 = 0; /* This matched exit status from /bin/echo */
     35  1.1     kamil 	const int sigval = SIGSTOP;
     36  1.1     kamil 	pid_t child, child2 = 0, wpid;
     37  1.1     kamil #if defined(TWAIT_HAVE_STATUS)
     38  1.1     kamil 	int status;
     39  1.1     kamil #endif
     40  1.3     kamil 	sigset_t set;
     41  1.1     kamil 	ptrace_state_t state;
     42  1.1     kamil 	const int slen = sizeof(state);
     43  1.1     kamil 	ptrace_event_t event;
     44  1.1     kamil 	const int elen = sizeof(event);
     45  1.1     kamil 
     46  1.1     kamil 	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
     47  1.1     kamil 
     48  1.7     kamil 	if (newpgrp)
     49  1.7     kamil 		atf_tc_skip("kernel panic (pg_jobc going negative)");
     50  1.7     kamil 
     51  1.1     kamil 	DPRINTF("Before forking process PID=%d\n", getpid());
     52  1.1     kamil 	SYSCALL_REQUIRE((child = fork()) != -1);
     53  1.1     kamil 	if (child == 0) {
     54  1.7     kamil 		if (newpgrp) {
     55  1.7     kamil 			DPRINTF("Before entering new process group");
     56  1.7     kamil 			setpgid(0, 0);
     57  1.7     kamil 		}
     58  1.7     kamil 
     59  1.1     kamil 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
     60  1.1     kamil 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
     61  1.1     kamil 
     62  1.1     kamil 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
     63  1.1     kamil 		FORKEE_ASSERT(raise(sigval) == 0);
     64  1.1     kamil 
     65  1.1     kamil 		if (strcmp(fn, "spawn") == 0) {
     66  1.1     kamil 			FORKEE_ASSERT_EQ(posix_spawn(&child2,
     67  1.1     kamil 			    arg[0], NULL, NULL, arg, NULL), 0);
     68  1.1     kamil 		} else {
     69  1.1     kamil 			if (strcmp(fn, "fork") == 0) {
     70  1.1     kamil 				FORKEE_ASSERT((child2 = fork()) != -1);
     71  1.1     kamil 			} else if (strcmp(fn, "vfork") == 0) {
     72  1.1     kamil 				FORKEE_ASSERT((child2 = vfork()) != -1);
     73  1.1     kamil 			}
     74  1.1     kamil 
     75  1.1     kamil 			if (child2 == 0)
     76  1.1     kamil 				_exit(exitval2);
     77  1.1     kamil 		}
     78  1.1     kamil 		FORKEE_REQUIRE_SUCCESS
     79  1.1     kamil 		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
     80  1.1     kamil 
     81  1.1     kamil 		forkee_status_exited(status, exitval2);
     82  1.1     kamil 
     83  1.1     kamil 		DPRINTF("Before exiting of the child process\n");
     84  1.1     kamil 		_exit(exitval);
     85  1.1     kamil 	}
     86  1.1     kamil 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
     87  1.1     kamil 
     88  1.1     kamil 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
     89  1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
     90  1.1     kamil 
     91  1.1     kamil 	validate_status_stopped(status, sigval);
     92  1.1     kamil 
     93  1.1     kamil 	DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n",
     94  1.1     kamil 	    trackspawn ? "|PTRACE_POSIX_SPAWN" : "",
     95  1.1     kamil 	    trackfork ? "|PTRACE_FORK" : "",
     96  1.1     kamil 	    trackvfork ? "|PTRACE_VFORK" : "",
     97  1.1     kamil 	    trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
     98  1.1     kamil 	event.pe_set_event = 0;
     99  1.1     kamil 	if (trackspawn)
    100  1.1     kamil 		event.pe_set_event |= PTRACE_POSIX_SPAWN;
    101  1.1     kamil 	if (trackfork)
    102  1.1     kamil 		event.pe_set_event |= PTRACE_FORK;
    103  1.1     kamil 	if (trackvfork)
    104  1.1     kamil 		event.pe_set_event |= PTRACE_VFORK;
    105  1.1     kamil 	if (trackvforkdone)
    106  1.1     kamil 		event.pe_set_event |= PTRACE_VFORK_DONE;
    107  1.1     kamil 	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
    108  1.1     kamil 
    109  1.3     kamil 	/*
    110  1.3     kamil 	 * Ignore interception of the SIGCHLD signals.
    111  1.3     kamil 	 *
    112  1.3     kamil 	 * SIGCHLD once blocked is discarded by the kernel as it has the
    113  1.3     kamil 	 * SA_IGNORE property. During the fork(2) operation all signals can be
    114  1.3     kamil 	 * shortly blocked and missed (unless there is a registered signal
    115  1.3     kamil 	 * handler in the traced child). This leads to a race in this test if
    116  1.3     kamil 	 * there would be an intention to catch SIGCHLD.
    117  1.3     kamil 	 */
    118  1.3     kamil 	sigemptyset(&set);
    119  1.3     kamil 	sigaddset(&set, SIGCHLD);
    120  1.3     kamil 	SYSCALL_REQUIRE(ptrace(PT_SET_SIGPASS, child, &set, sizeof(set)) != -1);
    121  1.3     kamil 
    122  1.1     kamil 	DPRINTF("Before resuming the child process where it left off and "
    123  1.1     kamil 	    "without signal to be sent\n");
    124  1.1     kamil 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    125  1.1     kamil 
    126  1.1     kamil #if defined(TWAIT_HAVE_PID)
    127  1.1     kamil 	if ((trackspawn && strcmp(fn, "spawn") == 0) ||
    128  1.1     kamil 	    (trackfork && strcmp(fn, "fork") == 0) ||
    129  1.1     kamil 	    (trackvfork && strcmp(fn, "vfork") == 0)) {
    130  1.1     kamil 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
    131  1.1     kamil 		    child);
    132  1.1     kamil 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
    133  1.1     kamil 		    child);
    134  1.1     kamil 
    135  1.1     kamil 		validate_status_stopped(status, SIGTRAP);
    136  1.1     kamil 
    137  1.1     kamil 		SYSCALL_REQUIRE(
    138  1.1     kamil 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
    139  1.1     kamil 		if (trackspawn && strcmp(fn, "spawn") == 0) {
    140  1.1     kamil 			ATF_REQUIRE_EQ(
    141  1.1     kamil 			    state.pe_report_event & PTRACE_POSIX_SPAWN,
    142  1.1     kamil 			       PTRACE_POSIX_SPAWN);
    143  1.1     kamil 		}
    144  1.1     kamil 		if (trackfork && strcmp(fn, "fork") == 0) {
    145  1.1     kamil 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
    146  1.1     kamil 			       PTRACE_FORK);
    147  1.1     kamil 		}
    148  1.1     kamil 		if (trackvfork && strcmp(fn, "vfork") == 0) {
    149  1.1     kamil 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
    150  1.1     kamil 			       PTRACE_VFORK);
    151  1.1     kamil 		}
    152  1.1     kamil 
    153  1.1     kamil 		child2 = state.pe_other_pid;
    154  1.1     kamil 		DPRINTF("Reported ptrace event with forkee %d\n", child2);
    155  1.1     kamil 
    156  1.1     kamil 		DPRINTF("Before calling %s() for the forkee %d of the child "
    157  1.1     kamil 		    "%d\n", TWAIT_FNAME, child2, child);
    158  1.1     kamil 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
    159  1.1     kamil 		    child2);
    160  1.1     kamil 
    161  1.1     kamil 		validate_status_stopped(status, SIGTRAP);
    162  1.1     kamil 
    163  1.1     kamil 		SYSCALL_REQUIRE(
    164  1.1     kamil 		    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
    165  1.1     kamil 		if (trackspawn && strcmp(fn, "spawn") == 0) {
    166  1.1     kamil 			ATF_REQUIRE_EQ(
    167  1.1     kamil 			    state.pe_report_event & PTRACE_POSIX_SPAWN,
    168  1.1     kamil 			       PTRACE_POSIX_SPAWN);
    169  1.1     kamil 		}
    170  1.1     kamil 		if (trackfork && strcmp(fn, "fork") == 0) {
    171  1.1     kamil 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
    172  1.1     kamil 			       PTRACE_FORK);
    173  1.1     kamil 		}
    174  1.1     kamil 		if (trackvfork && strcmp(fn, "vfork") == 0) {
    175  1.1     kamil 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
    176  1.1     kamil 			       PTRACE_VFORK);
    177  1.1     kamil 		}
    178  1.1     kamil 
    179  1.1     kamil 		ATF_REQUIRE_EQ(state.pe_other_pid, child);
    180  1.1     kamil 
    181  1.1     kamil 		DPRINTF("Before resuming the forkee process where it left off "
    182  1.1     kamil 		    "and without signal to be sent\n");
    183  1.1     kamil 		SYSCALL_REQUIRE(
    184  1.1     kamil 		    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
    185  1.1     kamil 
    186  1.1     kamil 		DPRINTF("Before resuming the child process where it left off "
    187  1.1     kamil 		    "and without signal to be sent\n");
    188  1.1     kamil 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    189  1.1     kamil 	}
    190  1.1     kamil #endif
    191  1.1     kamil 
    192  1.1     kamil 	if (trackvforkdone && strcmp(fn, "vfork") == 0) {
    193  1.1     kamil 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
    194  1.1     kamil 		    child);
    195  1.1     kamil 		TWAIT_REQUIRE_SUCCESS(
    196  1.1     kamil 		    wpid = TWAIT_GENERIC(child, &status, 0), child);
    197  1.1     kamil 
    198  1.1     kamil 		validate_status_stopped(status, SIGTRAP);
    199  1.1     kamil 
    200  1.1     kamil 		SYSCALL_REQUIRE(
    201  1.1     kamil 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
    202  1.1     kamil 		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
    203  1.1     kamil 
    204  1.1     kamil 		child2 = state.pe_other_pid;
    205  1.1     kamil 		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
    206  1.1     kamil 		    child2);
    207  1.1     kamil 
    208  1.1     kamil 		DPRINTF("Before resuming the child process where it left off "
    209  1.1     kamil 		    "and without signal to be sent\n");
    210  1.1     kamil 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    211  1.1     kamil 	}
    212  1.1     kamil 
    213  1.1     kamil #if defined(TWAIT_HAVE_PID)
    214  1.1     kamil 	if ((trackspawn && strcmp(fn, "spawn") == 0) ||
    215  1.1     kamil 	    (trackfork && strcmp(fn, "fork") == 0) ||
    216  1.1     kamil 	    (trackvfork && strcmp(fn, "vfork") == 0)) {
    217  1.1     kamil 		DPRINTF("Before calling %s() for the forkee - expected exited"
    218  1.1     kamil 		    "\n", TWAIT_FNAME);
    219  1.1     kamil 		TWAIT_REQUIRE_SUCCESS(
    220  1.1     kamil 		    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
    221  1.1     kamil 
    222  1.1     kamil 		validate_status_exited(status, exitval2);
    223  1.1     kamil 
    224  1.1     kamil 		DPRINTF("Before calling %s() for the forkee - expected no "
    225  1.1     kamil 		    "process\n", TWAIT_FNAME);
    226  1.1     kamil 		TWAIT_REQUIRE_FAILURE(ECHILD,
    227  1.1     kamil 		    wpid = TWAIT_GENERIC(child2, &status, 0));
    228  1.1     kamil 	}
    229  1.1     kamil #endif
    230  1.1     kamil 
    231  1.1     kamil 	DPRINTF("Before calling %s() for the child - expected exited\n",
    232  1.1     kamil 	    TWAIT_FNAME);
    233  1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    234  1.1     kamil 
    235  1.1     kamil 	validate_status_exited(status, exitval);
    236  1.1     kamil 
    237  1.1     kamil 	DPRINTF("Before calling %s() for the child - expected no process\n",
    238  1.1     kamil 	    TWAIT_FNAME);
    239  1.1     kamil 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
    240  1.1     kamil }
    241  1.1     kamil 
    242  1.7     kamil #define FORK_TEST2(name,fun,tspawn,tfork,tvfork,tvforkdone,newpgrp)	\
    243  1.1     kamil ATF_TC(name);								\
    244  1.1     kamil ATF_TC_HEAD(name, tc)							\
    245  1.1     kamil {									\
    246  1.1     kamil 	atf_tc_set_md_var(tc, "descr", "Verify " fun "() "		\
    247  1.7     kamil 	    "called with 0%s%s%s%s in EVENT_MASK%s",			\
    248  1.1     kamil 	    tspawn ? "|PTRACE_POSIX_SPAWN" : "",			\
    249  1.1     kamil 	    tfork ? "|PTRACE_FORK" : "",				\
    250  1.1     kamil 	    tvfork ? "|PTRACE_VFORK" : "",				\
    251  1.7     kamil 	    tvforkdone ? "|PTRACE_VFORK_DONE" : "",			\
    252  1.7     kamil 	    newpgrp ? " and the traced processes call setpgrp(0,0)":"");\
    253  1.1     kamil }									\
    254  1.1     kamil 									\
    255  1.1     kamil ATF_TC_BODY(name, tc)							\
    256  1.1     kamil {									\
    257  1.1     kamil 									\
    258  1.7     kamil 	fork_body(fun, tspawn, tfork, tvfork, tvforkdone, newpgrp);	\
    259  1.1     kamil }
    260  1.1     kamil 
    261  1.7     kamil #define FORK_TEST(name,fun,tspawn,tfork,tvfork,tvforkdone)		\
    262  1.7     kamil 	FORK_TEST2(name,fun,tspawn,tfork,tvfork,tvforkdone,false)
    263  1.7     kamil 
    264  1.1     kamil FORK_TEST(fork1, "fork", false, false, false, false)
    265  1.1     kamil #if defined(TWAIT_HAVE_PID)
    266  1.1     kamil FORK_TEST(fork2, "fork", false, true, false, false)
    267  1.1     kamil FORK_TEST(fork3, "fork", false, false, true, false)
    268  1.1     kamil FORK_TEST(fork4, "fork", false, true, true, false)
    269  1.1     kamil #endif
    270  1.1     kamil FORK_TEST(fork5, "fork", false, false, false, true)
    271  1.1     kamil #if defined(TWAIT_HAVE_PID)
    272  1.1     kamil FORK_TEST(fork6, "fork", false, true, false, true)
    273  1.1     kamil FORK_TEST(fork7, "fork", false, false, true, true)
    274  1.1     kamil FORK_TEST(fork8, "fork", false, true, true, true)
    275  1.1     kamil #endif
    276  1.1     kamil FORK_TEST(fork9, "fork", true, false, false, false)
    277  1.1     kamil #if defined(TWAIT_HAVE_PID)
    278  1.1     kamil FORK_TEST(fork10, "fork", true, true, false, false)
    279  1.1     kamil FORK_TEST(fork11, "fork", true, false, true, false)
    280  1.1     kamil FORK_TEST(fork12, "fork", true, true, true, false)
    281  1.1     kamil #endif
    282  1.1     kamil FORK_TEST(fork13, "fork", true, false, false, true)
    283  1.1     kamil #if defined(TWAIT_HAVE_PID)
    284  1.1     kamil FORK_TEST(fork14, "fork", true, true, false, true)
    285  1.1     kamil FORK_TEST(fork15, "fork", true, false, true, true)
    286  1.1     kamil FORK_TEST(fork16, "fork", true, true, true, true)
    287  1.1     kamil #endif
    288  1.1     kamil 
    289  1.7     kamil #if defined(TWAIT_HAVE_PID)
    290  1.7     kamil FORK_TEST2(fork_setpgid, "fork", true, true, true, true, true)
    291  1.7     kamil #endif
    292  1.7     kamil 
    293  1.1     kamil FORK_TEST(vfork1, "vfork", false, false, false, false)
    294  1.1     kamil #if defined(TWAIT_HAVE_PID)
    295  1.1     kamil FORK_TEST(vfork2, "vfork", false, true, false, false)
    296  1.1     kamil FORK_TEST(vfork3, "vfork", false, false, true, false)
    297  1.1     kamil FORK_TEST(vfork4, "vfork", false, true, true, false)
    298  1.1     kamil #endif
    299  1.1     kamil FORK_TEST(vfork5, "vfork", false, false, false, true)
    300  1.1     kamil #if defined(TWAIT_HAVE_PID)
    301  1.1     kamil FORK_TEST(vfork6, "vfork", false, true, false, true)
    302  1.1     kamil FORK_TEST(vfork7, "vfork", false, false, true, true)
    303  1.1     kamil FORK_TEST(vfork8, "vfork", false, true, true, true)
    304  1.1     kamil #endif
    305  1.1     kamil FORK_TEST(vfork9, "vfork", true, false, false, false)
    306  1.1     kamil #if defined(TWAIT_HAVE_PID)
    307  1.1     kamil FORK_TEST(vfork10, "vfork", true, true, false, false)
    308  1.1     kamil FORK_TEST(vfork11, "vfork", true, false, true, false)
    309  1.1     kamil FORK_TEST(vfork12, "vfork", true, true, true, false)
    310  1.1     kamil #endif
    311  1.1     kamil FORK_TEST(vfork13, "vfork", true, false, false, true)
    312  1.1     kamil #if defined(TWAIT_HAVE_PID)
    313  1.1     kamil FORK_TEST(vfork14, "vfork", true, true, false, true)
    314  1.1     kamil FORK_TEST(vfork15, "vfork", true, false, true, true)
    315  1.1     kamil FORK_TEST(vfork16, "vfork", true, true, true, true)
    316  1.1     kamil #endif
    317  1.1     kamil 
    318  1.7     kamil #if defined(TWAIT_HAVE_PID)
    319  1.7     kamil FORK_TEST2(vfork_setpgid, "vfork", true, true, true, true, true)
    320  1.7     kamil #endif
    321  1.7     kamil 
    322  1.1     kamil FORK_TEST(posix_spawn1, "spawn", false, false, false, false)
    323  1.1     kamil FORK_TEST(posix_spawn2, "spawn", false, true, false, false)
    324  1.1     kamil FORK_TEST(posix_spawn3, "spawn", false, false, true, false)
    325  1.1     kamil FORK_TEST(posix_spawn4, "spawn", false, true, true, false)
    326  1.1     kamil FORK_TEST(posix_spawn5, "spawn", false, false, false, true)
    327  1.1     kamil FORK_TEST(posix_spawn6, "spawn", false, true, false, true)
    328  1.1     kamil FORK_TEST(posix_spawn7, "spawn", false, false, true, true)
    329  1.1     kamil FORK_TEST(posix_spawn8, "spawn", false, true, true, true)
    330  1.1     kamil #if defined(TWAIT_HAVE_PID)
    331  1.1     kamil FORK_TEST(posix_spawn9, "spawn", true, false, false, false)
    332  1.1     kamil FORK_TEST(posix_spawn10, "spawn", true, true, false, false)
    333  1.1     kamil FORK_TEST(posix_spawn11, "spawn", true, false, true, false)
    334  1.1     kamil FORK_TEST(posix_spawn12, "spawn", true, true, true, false)
    335  1.1     kamil FORK_TEST(posix_spawn13, "spawn", true, false, false, true)
    336  1.1     kamil FORK_TEST(posix_spawn14, "spawn", true, true, false, true)
    337  1.1     kamil FORK_TEST(posix_spawn15, "spawn", true, false, true, true)
    338  1.1     kamil FORK_TEST(posix_spawn16, "spawn", true, true, true, true)
    339  1.1     kamil #endif
    340  1.1     kamil 
    341  1.7     kamil #if defined(TWAIT_HAVE_PID)
    342  1.7     kamil FORK_TEST2(posix_spawn_setpgid, "spawn", true, true, true, true, true)
    343  1.7     kamil #endif
    344  1.7     kamil 
    345  1.1     kamil /// ----------------------------------------------------------------------------
    346  1.1     kamil 
    347  1.1     kamil #if defined(TWAIT_HAVE_PID)
    348  1.1     kamil static void
    349  1.1     kamil unrelated_tracer_fork_body(const char *fn, bool trackspawn, bool trackfork,
    350  1.7     kamil     bool trackvfork, bool trackvforkdone, bool newpgrp)
    351  1.1     kamil {
    352  1.1     kamil 	const int sigval = SIGSTOP;
    353  1.1     kamil 	struct msg_fds parent_tracee, parent_tracer;
    354  1.1     kamil 	const int exitval = 10;
    355  1.1     kamil 	const int exitval2 = 0; /* This matched exit status from /bin/echo */
    356  1.1     kamil 	pid_t tracee, tracer, wpid;
    357  1.1     kamil 	pid_t tracee2 = 0;
    358  1.1     kamil 	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
    359  1.1     kamil #if defined(TWAIT_HAVE_STATUS)
    360  1.1     kamil 	int status;
    361  1.1     kamil #endif
    362  1.1     kamil 
    363  1.6     kamil 	sigset_t set;
    364  1.1     kamil 	struct ptrace_siginfo info;
    365  1.1     kamil 	ptrace_state_t state;
    366  1.1     kamil 	const int slen = sizeof(state);
    367  1.1     kamil 	ptrace_event_t event;
    368  1.1     kamil 	const int elen = sizeof(event);
    369  1.1     kamil 
    370  1.1     kamil 	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
    371  1.1     kamil 
    372  1.7     kamil 	if (newpgrp)
    373  1.7     kamil 		atf_tc_skip("kernel panic (pg_jobc going negative)");
    374  1.7     kamil 
    375  1.1     kamil 	DPRINTF("Spawn tracee\n");
    376  1.1     kamil 	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
    377  1.1     kamil 	tracee = atf_utils_fork();
    378  1.1     kamil 	if (tracee == 0) {
    379  1.7     kamil 		if (newpgrp) {
    380  1.7     kamil 			DPRINTF("Before entering new process group");
    381  1.7     kamil 			setpgid(0, 0);
    382  1.7     kamil 		}
    383  1.7     kamil 
    384  1.1     kamil 		// Wait for parent to let us crash
    385  1.1     kamil 		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
    386  1.1     kamil 
    387  1.1     kamil 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
    388  1.1     kamil 		FORKEE_ASSERT(raise(sigval) == 0);
    389  1.1     kamil 
    390  1.1     kamil 		if (strcmp(fn, "spawn") == 0) {
    391  1.1     kamil 			FORKEE_ASSERT_EQ(posix_spawn(&tracee2,
    392  1.1     kamil 			    arg[0], NULL, NULL, arg, NULL), 0);
    393  1.1     kamil 		} else {
    394  1.1     kamil 			if (strcmp(fn, "fork") == 0) {
    395  1.1     kamil 				FORKEE_ASSERT((tracee2 = fork()) != -1);
    396  1.1     kamil 			} else if (strcmp(fn, "vfork") == 0) {
    397  1.1     kamil 				FORKEE_ASSERT((tracee2 = vfork()) != -1);
    398  1.1     kamil 			}
    399  1.1     kamil 
    400  1.1     kamil 			if (tracee2 == 0)
    401  1.1     kamil 				_exit(exitval2);
    402  1.1     kamil 		}
    403  1.1     kamil 		FORKEE_REQUIRE_SUCCESS
    404  1.1     kamil 		    (wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
    405  1.1     kamil 
    406  1.1     kamil 		forkee_status_exited(status, exitval2);
    407  1.1     kamil 
    408  1.1     kamil 		DPRINTF("Before exiting of the child process\n");
    409  1.1     kamil 		_exit(exitval);
    410  1.1     kamil 	}
    411  1.1     kamil 
    412  1.1     kamil 	DPRINTF("Spawn debugger\n");
    413  1.1     kamil 	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
    414  1.1     kamil 	tracer = atf_utils_fork();
    415  1.1     kamil 	if (tracer == 0) {
    416  1.1     kamil 		/* Fork again and drop parent to reattach to PID 1 */
    417  1.1     kamil 		tracer = atf_utils_fork();
    418  1.1     kamil 		if (tracer != 0)
    419  1.1     kamil 			_exit(exitval);
    420  1.1     kamil 
    421  1.1     kamil 		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
    422  1.1     kamil 		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
    423  1.1     kamil 
    424  1.1     kamil 		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
    425  1.1     kamil 		FORKEE_REQUIRE_SUCCESS(
    426  1.1     kamil 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
    427  1.1     kamil 
    428  1.1     kamil 		forkee_status_stopped(status, SIGSTOP);
    429  1.1     kamil 
    430  1.1     kamil 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
    431  1.1     kamil 		    "traced process\n");
    432  1.1     kamil 		SYSCALL_REQUIRE(
    433  1.1     kamil 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
    434  1.1     kamil 
    435  1.1     kamil 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    436  1.1     kamil 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
    437  1.1     kamil 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
    438  1.1     kamil 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
    439  1.1     kamil 
    440  1.1     kamil 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
    441  1.1     kamil 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
    442  1.1     kamil 
    443  1.1     kamil 		/* Resume tracee with PT_CONTINUE */
    444  1.1     kamil 		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
    445  1.1     kamil 
    446  1.1     kamil 		/* Inform parent that tracer has attached to tracee */
    447  1.1     kamil 		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
    448  1.1     kamil 
    449  1.1     kamil 		/* Wait for parent to tell use that tracee should have exited */
    450  1.1     kamil 		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
    451  1.1     kamil 
    452  1.1     kamil 		/* Wait for tracee and assert that it exited */
    453  1.1     kamil 		FORKEE_REQUIRE_SUCCESS(
    454  1.1     kamil 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
    455  1.1     kamil 
    456  1.1     kamil 		forkee_status_stopped(status, sigval);
    457  1.1     kamil 
    458  1.1     kamil 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
    459  1.1     kamil 		    "traced process\n");
    460  1.1     kamil 		SYSCALL_REQUIRE(
    461  1.1     kamil 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
    462  1.1     kamil 
    463  1.1     kamil 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    464  1.1     kamil 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
    465  1.1     kamil 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
    466  1.1     kamil 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
    467  1.1     kamil 
    468  1.1     kamil 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
    469  1.1     kamil 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
    470  1.1     kamil 
    471  1.1     kamil 		DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n",
    472  1.1     kamil 		    trackspawn ? "|PTRACE_POSIX_SPAWN" : "",
    473  1.1     kamil 		    trackfork ? "|PTRACE_FORK" : "",
    474  1.1     kamil 		    trackvfork ? "|PTRACE_VFORK" : "",
    475  1.1     kamil 		    trackvforkdone ? "|PTRACE_VFORK_DONE" : "", tracee);
    476  1.1     kamil 		event.pe_set_event = 0;
    477  1.1     kamil 		if (trackspawn)
    478  1.1     kamil 			event.pe_set_event |= PTRACE_POSIX_SPAWN;
    479  1.1     kamil 		if (trackfork)
    480  1.1     kamil 			event.pe_set_event |= PTRACE_FORK;
    481  1.1     kamil 		if (trackvfork)
    482  1.1     kamil 			event.pe_set_event |= PTRACE_VFORK;
    483  1.1     kamil 		if (trackvforkdone)
    484  1.1     kamil 			event.pe_set_event |= PTRACE_VFORK_DONE;
    485  1.1     kamil 		SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, tracee, &event, elen)
    486  1.1     kamil 		    != -1);
    487  1.1     kamil 
    488  1.6     kamil 		/*
    489  1.6     kamil 		 * Ignore interception of the SIGCHLD signals.
    490  1.6     kamil 		 *
    491  1.6     kamil 		 * SIGCHLD once blocked is discarded by the kernel as it has the
    492  1.6     kamil 		 * SA_IGNORE property. During the fork(2) operation all signals
    493  1.6     kamil 		 * can be shortly blocked and missed (unless there is a
    494  1.6     kamil 		 * registered signal handler in the traced child). This leads to
    495  1.6     kamil 		 * a race in this test if there would be an intention to catch
    496  1.6     kamil 		 * SIGCHLD.
    497  1.6     kamil 		 */
    498  1.6     kamil 		sigemptyset(&set);
    499  1.6     kamil 		sigaddset(&set, SIGCHLD);
    500  1.6     kamil 		SYSCALL_REQUIRE(ptrace(PT_SET_SIGPASS, tracee, &set,
    501  1.6     kamil 		    sizeof(set)) != -1);
    502  1.6     kamil 
    503  1.1     kamil 		DPRINTF("Before resuming the child process where it left off "
    504  1.1     kamil 		    "and without signal to be sent\n");
    505  1.1     kamil 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
    506  1.1     kamil 
    507  1.1     kamil 		if ((trackspawn && strcmp(fn, "spawn") == 0) ||
    508  1.1     kamil 		    (trackfork && strcmp(fn, "fork") == 0) ||
    509  1.1     kamil 		    (trackvfork && strcmp(fn, "vfork") == 0)) {
    510  1.1     kamil 			DPRINTF("Before calling %s() for the tracee %d\n", TWAIT_FNAME,
    511  1.1     kamil 			    tracee);
    512  1.1     kamil 			TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0),
    513  1.1     kamil 			    tracee);
    514  1.1     kamil 
    515  1.1     kamil 			validate_status_stopped(status, SIGTRAP);
    516  1.1     kamil 
    517  1.1     kamil 			SYSCALL_REQUIRE(
    518  1.1     kamil 			    ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1);
    519  1.1     kamil 			if (trackspawn && strcmp(fn, "spawn") == 0) {
    520  1.1     kamil 				ATF_REQUIRE_EQ(
    521  1.1     kamil 				    state.pe_report_event & PTRACE_POSIX_SPAWN,
    522  1.1     kamil 				       PTRACE_POSIX_SPAWN);
    523  1.1     kamil 			}
    524  1.1     kamil 			if (trackfork && strcmp(fn, "fork") == 0) {
    525  1.1     kamil 				ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
    526  1.1     kamil 				       PTRACE_FORK);
    527  1.1     kamil 			}
    528  1.1     kamil 			if (trackvfork && strcmp(fn, "vfork") == 0) {
    529  1.1     kamil 				ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
    530  1.1     kamil 				       PTRACE_VFORK);
    531  1.1     kamil 			}
    532  1.1     kamil 
    533  1.1     kamil 			tracee2 = state.pe_other_pid;
    534  1.1     kamil 			DPRINTF("Reported ptrace event with forkee %d\n", tracee2);
    535  1.1     kamil 
    536  1.1     kamil 			DPRINTF("Before calling %s() for the forkee %d of the tracee "
    537  1.1     kamil 			    "%d\n", TWAIT_FNAME, tracee2, tracee);
    538  1.1     kamil 			TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0),
    539  1.1     kamil 			    tracee2);
    540  1.1     kamil 
    541  1.1     kamil 			validate_status_stopped(status, SIGTRAP);
    542  1.1     kamil 
    543  1.1     kamil 			SYSCALL_REQUIRE(
    544  1.1     kamil 			    ptrace(PT_GET_PROCESS_STATE, tracee2, &state, slen) != -1);
    545  1.1     kamil 			if (trackspawn && strcmp(fn, "spawn") == 0) {
    546  1.1     kamil 				ATF_REQUIRE_EQ(
    547  1.1     kamil 				    state.pe_report_event & PTRACE_POSIX_SPAWN,
    548  1.1     kamil 				       PTRACE_POSIX_SPAWN);
    549  1.1     kamil 			}
    550  1.1     kamil 			if (trackfork && strcmp(fn, "fork") == 0) {
    551  1.1     kamil 				ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
    552  1.1     kamil 				       PTRACE_FORK);
    553  1.1     kamil 			}
    554  1.1     kamil 			if (trackvfork && strcmp(fn, "vfork") == 0) {
    555  1.1     kamil 				ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
    556  1.1     kamil 				       PTRACE_VFORK);
    557  1.1     kamil 			}
    558  1.1     kamil 
    559  1.1     kamil 			ATF_REQUIRE_EQ(state.pe_other_pid, tracee);
    560  1.1     kamil 
    561  1.1     kamil 			DPRINTF("Before resuming the forkee process where it left off "
    562  1.1     kamil 			    "and without signal to be sent\n");
    563  1.1     kamil 			SYSCALL_REQUIRE(
    564  1.1     kamil 			    ptrace(PT_CONTINUE, tracee2, (void *)1, 0) != -1);
    565  1.8  riastrad 
    566  1.1     kamil 			DPRINTF("Before resuming the tracee process where it left off "
    567  1.1     kamil 			    "and without signal to be sent\n");
    568  1.1     kamil 			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
    569  1.1     kamil 		}
    570  1.1     kamil 
    571  1.1     kamil 		if (trackvforkdone && strcmp(fn, "vfork") == 0) {
    572  1.1     kamil 			DPRINTF("Before calling %s() for the tracee %d\n", TWAIT_FNAME,
    573  1.1     kamil 			    tracee);
    574  1.1     kamil 			TWAIT_REQUIRE_SUCCESS(
    575  1.1     kamil 			    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
    576  1.1     kamil 
    577  1.1     kamil 			validate_status_stopped(status, SIGTRAP);
    578  1.1     kamil 
    579  1.1     kamil 			SYSCALL_REQUIRE(
    580  1.1     kamil 			    ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1);
    581  1.1     kamil 			ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
    582  1.1     kamil 
    583  1.1     kamil 			tracee2 = state.pe_other_pid;
    584  1.1     kamil 			DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
    585  1.1     kamil 			    tracee2);
    586  1.1     kamil 
    587  1.1     kamil 			DPRINTF("Before resuming the tracee process where it left off "
    588  1.1     kamil 			    "and without signal to be sent\n");
    589  1.1     kamil 			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
    590  1.1     kamil 		}
    591  1.1     kamil 
    592  1.1     kamil 		if ((trackspawn && strcmp(fn, "spawn") == 0) ||
    593  1.1     kamil 		    (trackfork && strcmp(fn, "fork") == 0) ||
    594  1.1     kamil 		    (trackvfork && strcmp(fn, "vfork") == 0)) {
    595  1.1     kamil 			DPRINTF("Before calling %s() for the forkee - expected exited"
    596  1.1     kamil 			    "\n", TWAIT_FNAME);
    597  1.1     kamil 			TWAIT_REQUIRE_SUCCESS(
    598  1.1     kamil 			    wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
    599  1.1     kamil 
    600  1.1     kamil 			validate_status_exited(status, exitval2);
    601  1.1     kamil 
    602  1.1     kamil 			DPRINTF("Before calling %s() for the forkee - expected no "
    603  1.1     kamil 			    "process\n", TWAIT_FNAME);
    604  1.1     kamil 			TWAIT_REQUIRE_FAILURE(ECHILD,
    605  1.1     kamil 			    wpid = TWAIT_GENERIC(tracee2, &status, 0));
    606  1.1     kamil 		}
    607  1.1     kamil 
    608  1.1     kamil 		DPRINTF("Before calling %s() for the tracee - expected exited\n",
    609  1.1     kamil 		    TWAIT_FNAME);
    610  1.1     kamil 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
    611  1.1     kamil 
    612  1.1     kamil 		validate_status_exited(status, exitval);
    613  1.1     kamil 
    614  1.1     kamil 		/* Inform parent that tracer is exiting normally */
    615  1.1     kamil 		CHILD_TO_PARENT("tracer done", parent_tracer, msg);
    616  1.1     kamil 
    617  1.1     kamil 		DPRINTF("Before exiting of the tracer process\n");
    618  1.1     kamil 		_exit(0 /* collect by initproc */);
    619  1.1     kamil 	}
    620  1.1     kamil 
    621  1.1     kamil 	DPRINTF("Wait for the tracer process (direct child) to exit "
    622  1.1     kamil 	    "calling %s()\n", TWAIT_FNAME);
    623  1.1     kamil 	TWAIT_REQUIRE_SUCCESS(
    624  1.1     kamil 	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
    625  1.1     kamil 
    626  1.1     kamil 	validate_status_exited(status, exitval);
    627  1.1     kamil 
    628  1.1     kamil 	DPRINTF("Wait for the non-exited tracee process with %s()\n",
    629  1.1     kamil 	    TWAIT_FNAME);
    630  1.1     kamil 	TWAIT_REQUIRE_SUCCESS(
    631  1.1     kamil 	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
    632  1.1     kamil 
    633  1.1     kamil 	DPRINTF("Wait for the tracer to attach to the tracee\n");
    634  1.1     kamil 	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
    635  1.1     kamil 
    636  1.1     kamil 	DPRINTF("Resume the tracee and let it crash\n");
    637  1.1     kamil 	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
    638  1.1     kamil 
    639  1.1     kamil 	DPRINTF("Resume the tracer and let it detect crashed tracee\n");
    640  1.1     kamil 	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
    641  1.1     kamil 
    642  1.1     kamil 	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
    643  1.1     kamil 	    TWAIT_FNAME);
    644  1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
    645  1.1     kamil 
    646  1.1     kamil 	validate_status_exited(status, exitval);
    647  1.1     kamil 
    648  1.1     kamil 	DPRINTF("Await normal exit of tracer\n");
    649  1.1     kamil 	PARENT_FROM_CHILD("tracer done", parent_tracer, msg);
    650  1.1     kamil 
    651  1.1     kamil 	msg_close(&parent_tracer);
    652  1.1     kamil 	msg_close(&parent_tracee);
    653  1.1     kamil }
    654  1.1     kamil 
    655  1.7     kamil #define UNRELATED_TRACER_FORK_TEST2(name,fun,tspawn,tfork,tvfork,tvforkdone,newpgrp)\
    656  1.1     kamil ATF_TC(name);								\
    657  1.1     kamil ATF_TC_HEAD(name, tc)							\
    658  1.1     kamil {									\
    659  1.1     kamil 	atf_tc_set_md_var(tc, "descr", "Verify " fun "() "		\
    660  1.7     kamil 	    "called with 0%s%s%s%s in EVENT_MASK%s",			\
    661  1.1     kamil 	    tspawn ? "|PTRACE_POSIX_SPAWN" : "",			\
    662  1.1     kamil 	    tfork ? "|PTRACE_FORK" : "",				\
    663  1.1     kamil 	    tvfork ? "|PTRACE_VFORK" : "",				\
    664  1.7     kamil 	    tvforkdone ? "|PTRACE_VFORK_DONE" : "",			\
    665  1.7     kamil 	    newpgrp ? " and the traced processes call setpgrp(0,0)":"");\
    666  1.1     kamil }									\
    667  1.1     kamil 									\
    668  1.1     kamil ATF_TC_BODY(name, tc)							\
    669  1.1     kamil {									\
    670  1.1     kamil 									\
    671  1.1     kamil 	unrelated_tracer_fork_body(fun, tspawn, tfork, tvfork,		\
    672  1.7     kamil 	    tvforkdone, newpgrp);					\
    673  1.1     kamil }
    674  1.1     kamil 
    675  1.7     kamil #define UNRELATED_TRACER_FORK_TEST(name,fun,tspawn,tfork,tvfork,tvforkdone)	\
    676  1.7     kamil 	UNRELATED_TRACER_FORK_TEST2(name,fun,tspawn,tfork,tvfork,tvforkdone,false)
    677  1.7     kamil 
    678  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork1, "fork", false, false, false, false)
    679  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork2, "fork", false, true, false, false)
    680  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork3, "fork", false, false, true, false)
    681  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork4, "fork", false, true, true, false)
    682  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork5, "fork", false, false, false, true)
    683  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork6, "fork", false, true, false, true)
    684  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork7, "fork", false, false, true, true)
    685  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork8, "fork", false, true, true, true)
    686  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork9, "fork", true, false, false, false)
    687  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork10, "fork", true, true, false, false)
    688  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork11, "fork", true, false, true, false)
    689  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork12, "fork", true, true, true, false)
    690  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork13, "fork", true, false, false, true)
    691  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork14, "fork", true, true, false, true)
    692  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork15, "fork", true, false, true, true)
    693  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork16, "fork", true, true, true, true)
    694  1.1     kamil 
    695  1.7     kamil UNRELATED_TRACER_FORK_TEST2(unrelated_tracer_fork_setpgid, "fork", true, true, true, true, true)
    696  1.7     kamil 
    697  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork1, "vfork", false, false, false, false)
    698  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork2, "vfork", false, true, false, false)
    699  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork3, "vfork", false, false, true, false)
    700  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork4, "vfork", false, true, true, false)
    701  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork5, "vfork", false, false, false, true)
    702  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork6, "vfork", false, true, false, true)
    703  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork7, "vfork", false, false, true, true)
    704  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork8, "vfork", false, true, true, true)
    705  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork9, "vfork", true, false, false, false)
    706  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork10, "vfork", true, true, false, false)
    707  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork11, "vfork", true, false, true, false)
    708  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork12, "vfork", true, true, true, false)
    709  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork13, "vfork", true, false, false, true)
    710  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork14, "vfork", true, true, false, true)
    711  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork15, "vfork", true, false, true, true)
    712  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork16, "vfork", true, true, true, true)
    713  1.1     kamil 
    714  1.7     kamil UNRELATED_TRACER_FORK_TEST2(unrelated_tracer_vfork_setpgid, "vfork", true, true, true, true, true)
    715  1.7     kamil 
    716  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn1, "spawn", false, false, false, false)
    717  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn2, "spawn", false, true, false, false)
    718  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn3, "spawn", false, false, true, false)
    719  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn4, "spawn", false, true, true, false)
    720  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn5, "spawn", false, false, false, true)
    721  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn6, "spawn", false, true, false, true)
    722  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn7, "spawn", false, false, true, true)
    723  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn8, "spawn", false, true, true, true)
    724  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn9, "spawn", true, false, false, false)
    725  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn10, "spawn", true, true, false, false)
    726  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn11, "spawn", true, false, true, false)
    727  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn12, "spawn", true, true, true, false)
    728  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn13, "spawn", true, false, false, true)
    729  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn14, "spawn", true, true, false, true)
    730  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn15, "spawn", true, false, true, true)
    731  1.1     kamil UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn16, "spawn", true, true, true, true)
    732  1.7     kamil 
    733  1.7     kamil UNRELATED_TRACER_FORK_TEST2(unrelated_tracer_posix_spawn_setpgid, "spawn", true, true, true, true, true)
    734  1.1     kamil #endif
    735  1.1     kamil 
    736  1.1     kamil /// ----------------------------------------------------------------------------
    737  1.1     kamil 
    738  1.1     kamil #if defined(TWAIT_HAVE_PID)
    739  1.1     kamil static void
    740  1.1     kamil fork_detach_forker_body(const char *fn, bool kill_process)
    741  1.1     kamil {
    742  1.1     kamil 	const int exitval = 5;
    743  1.1     kamil 	const int exitval2 = 0; /* Matches exit value from /bin/echo */
    744  1.1     kamil 	const int sigval = SIGSTOP;
    745  1.1     kamil 	pid_t child, child2 = 0, wpid;
    746  1.1     kamil #if defined(TWAIT_HAVE_STATUS)
    747  1.1     kamil 	int status;
    748  1.1     kamil #endif
    749  1.1     kamil 	ptrace_state_t state;
    750  1.1     kamil 	const int slen = sizeof(state);
    751  1.1     kamil 	ptrace_event_t event;
    752  1.1     kamil 	const int elen = sizeof(event);
    753  1.1     kamil 
    754  1.1     kamil 	int op;
    755  1.1     kamil 
    756  1.1     kamil 	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
    757  1.1     kamil 
    758  1.1     kamil 	DPRINTF("Before forking process PID=%d\n", getpid());
    759  1.1     kamil 	SYSCALL_REQUIRE((child = fork()) != -1);
    760  1.1     kamil 	if (child == 0) {
    761  1.1     kamil 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
    762  1.1     kamil 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
    763  1.1     kamil 
    764  1.1     kamil 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
    765  1.1     kamil 		FORKEE_ASSERT(raise(sigval) == 0);
    766  1.1     kamil 
    767  1.1     kamil 		if (strcmp(fn, "spawn") == 0) {
    768  1.1     kamil 			FORKEE_ASSERT_EQ(posix_spawn(&child2,
    769  1.1     kamil 			    arg[0], NULL, NULL, arg, NULL), 0);
    770  1.1     kamil 		} else  {
    771  1.1     kamil 			if (strcmp(fn, "fork") == 0) {
    772  1.1     kamil 				FORKEE_ASSERT((child2 = fork()) != -1);
    773  1.1     kamil 			} else {
    774  1.1     kamil 				FORKEE_ASSERT((child2 = vfork()) != -1);
    775  1.1     kamil 			}
    776  1.1     kamil 
    777  1.1     kamil 			if (child2 == 0)
    778  1.1     kamil 				_exit(exitval2);
    779  1.1     kamil 		}
    780  1.1     kamil 
    781  1.1     kamil 		FORKEE_REQUIRE_SUCCESS
    782  1.1     kamil 		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
    783  1.1     kamil 
    784  1.1     kamil 		forkee_status_exited(status, exitval2);
    785  1.1     kamil 
    786  1.1     kamil 		DPRINTF("Before exiting of the child process\n");
    787  1.1     kamil 		_exit(exitval);
    788  1.1     kamil 	}
    789  1.1     kamil 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
    790  1.1     kamil 
    791  1.1     kamil 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    792  1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    793  1.1     kamil 
    794  1.1     kamil 	validate_status_stopped(status, sigval);
    795  1.1     kamil 
    796  1.1     kamil 	DPRINTF("Set EVENT_MASK for the child %d\n", child);
    797  1.1     kamil 	event.pe_set_event = PTRACE_POSIX_SPAWN | PTRACE_FORK | PTRACE_VFORK
    798  1.1     kamil 		| PTRACE_VFORK_DONE;
    799  1.1     kamil 	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
    800  1.1     kamil 
    801  1.1     kamil 	DPRINTF("Before resuming the child process where it left off and "
    802  1.1     kamil 	    "without signal to be sent\n");
    803  1.1     kamil 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    804  1.1     kamil 
    805  1.1     kamil 	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
    806  1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    807  1.1     kamil 
    808  1.1     kamil 	validate_status_stopped(status, SIGTRAP);
    809  1.1     kamil 
    810  1.1     kamil 	SYSCALL_REQUIRE(
    811  1.1     kamil 	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
    812  1.1     kamil 
    813  1.1     kamil 	if (strcmp(fn, "spawn") == 0)
    814  1.1     kamil 		op = PTRACE_POSIX_SPAWN;
    815  1.1     kamil 	else if (strcmp(fn, "fork") == 0)
    816  1.1     kamil 		op = PTRACE_FORK;
    817  1.1     kamil 	else
    818  1.1     kamil 		op = PTRACE_VFORK;
    819  1.1     kamil 
    820  1.1     kamil 	ATF_REQUIRE_EQ(state.pe_report_event & op, op);
    821  1.1     kamil 
    822  1.1     kamil 	child2 = state.pe_other_pid;
    823  1.1     kamil 	DPRINTF("Reported ptrace event with forkee %d\n", child2);
    824  1.1     kamil 
    825  1.1     kamil 	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
    826  1.1     kamil 	    strcmp(fn, "vfork") == 0)
    827  1.1     kamil 		op = kill_process ? PT_KILL : PT_DETACH;
    828  1.1     kamil 	else
    829  1.1     kamil 		op = PT_CONTINUE;
    830  1.1     kamil 	SYSCALL_REQUIRE(ptrace(op, child, (void *)1, 0) != -1);
    831  1.1     kamil 
    832  1.1     kamil 	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
    833  1.1     kamil 	    TWAIT_FNAME, child2, child);
    834  1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
    835  1.1     kamil 
    836  1.1     kamil 	validate_status_stopped(status, SIGTRAP);
    837  1.1     kamil 
    838  1.1     kamil 	SYSCALL_REQUIRE(
    839  1.1     kamil 	    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
    840  1.1     kamil 	if (strcmp(fn, "spawn") == 0)
    841  1.1     kamil 		op = PTRACE_POSIX_SPAWN;
    842  1.1     kamil 	else if (strcmp(fn, "fork") == 0)
    843  1.1     kamil 		op = PTRACE_FORK;
    844  1.1     kamil 	else
    845  1.1     kamil 		op = PTRACE_VFORK;
    846  1.8  riastrad 
    847  1.1     kamil 	ATF_REQUIRE_EQ(state.pe_report_event & op, op);
    848  1.1     kamil 	ATF_REQUIRE_EQ(state.pe_other_pid, child);
    849  1.1     kamil 
    850  1.1     kamil 	DPRINTF("Before resuming the forkee process where it left off "
    851  1.1     kamil 	    "and without signal to be sent\n");
    852  1.1     kamil  	SYSCALL_REQUIRE(
    853  1.1     kamil 	    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
    854  1.1     kamil 
    855  1.1     kamil 	if (strcmp(fn, "vforkdone") == 0) {
    856  1.1     kamil 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
    857  1.1     kamil 		    child);
    858  1.1     kamil 		TWAIT_REQUIRE_SUCCESS(
    859  1.1     kamil 		    wpid = TWAIT_GENERIC(child, &status, 0), child);
    860  1.1     kamil 
    861  1.1     kamil 		validate_status_stopped(status, SIGTRAP);
    862  1.1     kamil 
    863  1.1     kamil 		SYSCALL_REQUIRE(
    864  1.1     kamil 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
    865  1.1     kamil 		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
    866  1.1     kamil 
    867  1.1     kamil 		child2 = state.pe_other_pid;
    868  1.1     kamil 		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
    869  1.1     kamil 		    child2);
    870  1.1     kamil 
    871  1.1     kamil 		op = kill_process ? PT_KILL : PT_DETACH;
    872  1.1     kamil 		DPRINTF("Before resuming the child process where it left off "
    873  1.1     kamil 		    "and without signal to be sent\n");
    874  1.1     kamil 		SYSCALL_REQUIRE(ptrace(op, child, (void *)1, 0) != -1);
    875  1.1     kamil 	}
    876  1.1     kamil 
    877  1.1     kamil 	DPRINTF("Before calling %s() for the forkee - expected exited\n",
    878  1.1     kamil 	    TWAIT_FNAME);
    879  1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
    880  1.1     kamil 
    881  1.1     kamil 	validate_status_exited(status, exitval2);
    882  1.1     kamil 
    883  1.1     kamil 	DPRINTF("Before calling %s() for the forkee - expected no process\n",
    884  1.1     kamil 	    TWAIT_FNAME);
    885  1.1     kamil 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child2, &status, 0));
    886  1.1     kamil 
    887  1.1     kamil 	DPRINTF("Before calling %s() for the forkee - expected exited\n",
    888  1.1     kamil 	    TWAIT_FNAME);
    889  1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    890  1.1     kamil 
    891  1.1     kamil 	if (kill_process) {
    892  1.1     kamil 		validate_status_signaled(status, SIGKILL, 0);
    893  1.1     kamil 	} else {
    894  1.1     kamil 		validate_status_exited(status, exitval);
    895  1.1     kamil 	}
    896  1.1     kamil 
    897  1.1     kamil 	DPRINTF("Before calling %s() for the child - expected no process\n",
    898  1.1     kamil 	    TWAIT_FNAME);
    899  1.1     kamil 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
    900  1.1     kamil }
    901  1.1     kamil 
    902  1.1     kamil #define FORK_DETACH_FORKER(name,event,kprocess)				\
    903  1.1     kamil ATF_TC(name);								\
    904  1.1     kamil ATF_TC_HEAD(name, tc)							\
    905  1.1     kamil {									\
    906  1.1     kamil 	atf_tc_set_md_var(tc, "descr", "Verify %s " event,		\
    907  1.1     kamil 	    kprocess ? "killed" : "detached");				\
    908  1.1     kamil }									\
    909  1.1     kamil 									\
    910  1.1     kamil ATF_TC_BODY(name, tc)							\
    911  1.1     kamil {									\
    912  1.1     kamil 									\
    913  1.1     kamil 	fork_detach_forker_body(event, kprocess);			\
    914  1.1     kamil }
    915  1.1     kamil 
    916  1.1     kamil FORK_DETACH_FORKER(posix_spawn_detach_spawner, "spawn", false)
    917  1.1     kamil FORK_DETACH_FORKER(fork_detach_forker, "fork", false)
    918  1.1     kamil FORK_DETACH_FORKER(vfork_detach_vforker, "vfork", false)
    919  1.1     kamil FORK_DETACH_FORKER(vfork_detach_vforkerdone, "vforkdone", false)
    920  1.1     kamil 
    921  1.1     kamil FORK_DETACH_FORKER(posix_spawn_kill_spawner, "spawn", true)
    922  1.1     kamil FORK_DETACH_FORKER(fork_kill_forker, "fork", true)
    923  1.1     kamil FORK_DETACH_FORKER(vfork_kill_vforker, "vfork", true)
    924  1.1     kamil FORK_DETACH_FORKER(vfork_kill_vforkerdone, "vforkdone", true)
    925  1.1     kamil #endif
    926  1.1     kamil 
    927  1.1     kamil /// ----------------------------------------------------------------------------
    928  1.1     kamil 
    929  1.1     kamil #if defined(TWAIT_HAVE_PID)
    930  1.1     kamil static void
    931  1.1     kamil unrelated_tracer_fork_detach_forker_body(const char *fn, bool kill_process)
    932  1.1     kamil {
    933  1.1     kamil 	const int sigval = SIGSTOP;
    934  1.1     kamil 	struct msg_fds parent_tracee, parent_tracer;
    935  1.1     kamil 	const int exitval = 10;
    936  1.1     kamil 	const int exitval2 = 0; /* This matched exit status from /bin/echo */
    937  1.1     kamil 	pid_t tracee, tracer, wpid;
    938  1.1     kamil 	pid_t tracee2 = 0;
    939  1.1     kamil 	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
    940  1.1     kamil #if defined(TWAIT_HAVE_STATUS)
    941  1.1     kamil 	int status;
    942  1.1     kamil #endif
    943  1.1     kamil 	int op;
    944  1.1     kamil 
    945  1.1     kamil 	struct ptrace_siginfo info;
    946  1.1     kamil 	ptrace_state_t state;
    947  1.1     kamil 	const int slen = sizeof(state);
    948  1.1     kamil 	ptrace_event_t event;
    949  1.1     kamil 	const int elen = sizeof(event);
    950  1.1     kamil 
    951  1.1     kamil 	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
    952  1.1     kamil 
    953  1.1     kamil 	DPRINTF("Spawn tracee\n");
    954  1.1     kamil 	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
    955  1.1     kamil 	tracee = atf_utils_fork();
    956  1.1     kamil 	if (tracee == 0) {
    957  1.1     kamil 		// Wait for parent to let us crash
    958  1.1     kamil 		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
    959  1.1     kamil 
    960  1.1     kamil 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
    961  1.1     kamil 		FORKEE_ASSERT(raise(sigval) == 0);
    962  1.1     kamil 
    963  1.1     kamil 		if (strcmp(fn, "spawn") == 0) {
    964  1.1     kamil 			FORKEE_ASSERT_EQ(posix_spawn(&tracee2,
    965  1.1     kamil 			    arg[0], NULL, NULL, arg, NULL), 0);
    966  1.1     kamil 		} else  {
    967  1.1     kamil 			if (strcmp(fn, "fork") == 0) {
    968  1.1     kamil 				FORKEE_ASSERT((tracee2 = fork()) != -1);
    969  1.1     kamil 			} else {
    970  1.1     kamil 				FORKEE_ASSERT((tracee2 = vfork()) != -1);
    971  1.1     kamil 			}
    972  1.1     kamil 
    973  1.1     kamil 			if (tracee2 == 0)
    974  1.1     kamil 				_exit(exitval2);
    975  1.1     kamil 		}
    976  1.1     kamil 
    977  1.1     kamil 		FORKEE_REQUIRE_SUCCESS
    978  1.1     kamil 		    (wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
    979  1.1     kamil 
    980  1.1     kamil 		forkee_status_exited(status, exitval2);
    981  1.1     kamil 
    982  1.1     kamil 		DPRINTF("Before exiting of the child process\n");
    983  1.1     kamil 		_exit(exitval);
    984  1.1     kamil 	}
    985  1.1     kamil 
    986  1.1     kamil 	DPRINTF("Spawn debugger\n");
    987  1.1     kamil 	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
    988  1.1     kamil 	tracer = atf_utils_fork();
    989  1.1     kamil 	if (tracer == 0) {
    990  1.1     kamil 		/* Fork again and drop parent to reattach to PID 1 */
    991  1.1     kamil 		tracer = atf_utils_fork();
    992  1.1     kamil 		if (tracer != 0)
    993  1.1     kamil 			_exit(exitval);
    994  1.1     kamil 
    995  1.1     kamil 		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
    996  1.1     kamil 		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
    997  1.1     kamil 
    998  1.1     kamil 		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
    999  1.1     kamil 		FORKEE_REQUIRE_SUCCESS(
   1000  1.1     kamil 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1001  1.1     kamil 
   1002  1.1     kamil 		forkee_status_stopped(status, SIGSTOP);
   1003  1.1     kamil 
   1004  1.1     kamil 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
   1005  1.1     kamil 		    "traced process\n");
   1006  1.1     kamil 		SYSCALL_REQUIRE(
   1007  1.1     kamil 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
   1008  1.1     kamil 
   1009  1.1     kamil 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
   1010  1.1     kamil 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
   1011  1.1     kamil 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
   1012  1.1     kamil 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
   1013  1.1     kamil 
   1014  1.1     kamil 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
   1015  1.1     kamil 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
   1016  1.1     kamil 
   1017  1.1     kamil 		/* Resume tracee with PT_CONTINUE */
   1018  1.1     kamil 		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
   1019  1.1     kamil 
   1020  1.1     kamil 		/* Inform parent that tracer has attached to tracee */
   1021  1.1     kamil 		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
   1022  1.1     kamil 
   1023  1.1     kamil 		/* Wait for parent to tell use that tracee should have exited */
   1024  1.1     kamil 		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
   1025  1.1     kamil 
   1026  1.1     kamil 		/* Wait for tracee and assert that it exited */
   1027  1.1     kamil 		FORKEE_REQUIRE_SUCCESS(
   1028  1.1     kamil 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1029  1.1     kamil 
   1030  1.1     kamil 		forkee_status_stopped(status, sigval);
   1031  1.1     kamil 
   1032  1.1     kamil 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
   1033  1.1     kamil 		    "traced process\n");
   1034  1.1     kamil 		SYSCALL_REQUIRE(
   1035  1.1     kamil 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
   1036  1.1     kamil 
   1037  1.1     kamil 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
   1038  1.1     kamil 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
   1039  1.1     kamil 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
   1040  1.1     kamil 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
   1041  1.1     kamil 
   1042  1.1     kamil 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
   1043  1.1     kamil 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
   1044  1.1     kamil 
   1045  1.1     kamil 		DPRINTF("Set EVENT_MASK for the child %d\n", tracee);
   1046  1.1     kamil 		event.pe_set_event = PTRACE_POSIX_SPAWN | PTRACE_FORK | PTRACE_VFORK
   1047  1.1     kamil 			| PTRACE_VFORK_DONE;
   1048  1.1     kamil 		SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, tracee, &event, elen) != -1);
   1049  1.1     kamil 
   1050  1.1     kamil 		DPRINTF("Before resuming the child process where it left off and "
   1051  1.1     kamil 		    "without signal to be sent\n");
   1052  1.1     kamil 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
   1053  1.1     kamil 
   1054  1.1     kamil 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, tracee);
   1055  1.1     kamil 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1056  1.1     kamil 
   1057  1.1     kamil 		validate_status_stopped(status, SIGTRAP);
   1058  1.1     kamil 
   1059  1.1     kamil 		SYSCALL_REQUIRE(
   1060  1.1     kamil 		    ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1);
   1061  1.1     kamil 
   1062  1.1     kamil 		if (strcmp(fn, "spawn") == 0)
   1063  1.1     kamil 			op = PTRACE_POSIX_SPAWN;
   1064  1.1     kamil 		else if (strcmp(fn, "fork") == 0)
   1065  1.1     kamil 			op = PTRACE_FORK;
   1066  1.1     kamil 		else
   1067  1.1     kamil 			op = PTRACE_VFORK;
   1068  1.1     kamil 
   1069  1.1     kamil 		ATF_REQUIRE_EQ(state.pe_report_event & op, op);
   1070  1.1     kamil 
   1071  1.1     kamil 		tracee2 = state.pe_other_pid;
   1072  1.1     kamil 		DPRINTF("Reported ptrace event with forkee %d\n", tracee2);
   1073  1.1     kamil 		if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
   1074  1.1     kamil 		    strcmp(fn, "vfork") == 0)
   1075  1.1     kamil 			op = kill_process ? PT_KILL : PT_DETACH;
   1076  1.1     kamil 		else
   1077  1.1     kamil 			op = PT_CONTINUE;
   1078  1.1     kamil 		SYSCALL_REQUIRE(ptrace(op, tracee, (void *)1, 0) != -1);
   1079  1.1     kamil 
   1080  1.1     kamil 		DPRINTF("Before calling %s() for the forkee %d of the tracee %d\n",
   1081  1.1     kamil 		    TWAIT_FNAME, tracee2, tracee);
   1082  1.1     kamil 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
   1083  1.1     kamil 
   1084  1.1     kamil 		validate_status_stopped(status, SIGTRAP);
   1085  1.1     kamil 
   1086  1.1     kamil 		SYSCALL_REQUIRE(
   1087  1.1     kamil 		    ptrace(PT_GET_PROCESS_STATE, tracee2, &state, slen) != -1);
   1088  1.1     kamil 		if (strcmp(fn, "spawn") == 0)
   1089  1.1     kamil 			op = PTRACE_POSIX_SPAWN;
   1090  1.1     kamil 		else if (strcmp(fn, "fork") == 0)
   1091  1.1     kamil 			op = PTRACE_FORK;
   1092  1.1     kamil 		else
   1093  1.1     kamil 			op = PTRACE_VFORK;
   1094  1.1     kamil 
   1095  1.1     kamil 		ATF_REQUIRE_EQ(state.pe_report_event & op, op);
   1096  1.1     kamil 		ATF_REQUIRE_EQ(state.pe_other_pid, tracee);
   1097  1.1     kamil 
   1098  1.1     kamil 		DPRINTF("Before resuming the forkee process where it left off "
   1099  1.1     kamil 		    "and without signal to be sent\n");
   1100  1.1     kamil 		SYSCALL_REQUIRE(
   1101  1.1     kamil 		    ptrace(PT_CONTINUE, tracee2, (void *)1, 0) != -1);
   1102  1.1     kamil 
   1103  1.1     kamil 		if (strcmp(fn, "vforkdone") == 0) {
   1104  1.1     kamil 			DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
   1105  1.1     kamil 			    tracee);
   1106  1.1     kamil 			TWAIT_REQUIRE_SUCCESS(
   1107  1.1     kamil 			    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1108  1.1     kamil 
   1109  1.1     kamil 			validate_status_stopped(status, SIGTRAP);
   1110  1.1     kamil 
   1111  1.1     kamil 			SYSCALL_REQUIRE(
   1112  1.1     kamil 			    ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1);
   1113  1.1     kamil 			ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
   1114  1.1     kamil 
   1115  1.1     kamil 			tracee2 = state.pe_other_pid;
   1116  1.1     kamil 			DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
   1117  1.1     kamil 			    tracee2);
   1118  1.1     kamil 
   1119  1.1     kamil 			op = kill_process ? PT_KILL : PT_DETACH;
   1120  1.1     kamil 			DPRINTF("Before resuming the child process where it left off "
   1121  1.1     kamil 			    "and without signal to be sent\n");
   1122  1.1     kamil 			SYSCALL_REQUIRE(ptrace(op, tracee, (void *)1, 0) != -1);
   1123  1.1     kamil 		}
   1124  1.1     kamil 
   1125  1.1     kamil 		DPRINTF("Before calling %s() for the forkee - expected exited\n",
   1126  1.1     kamil 		    TWAIT_FNAME);
   1127  1.1     kamil 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
   1128  1.1     kamil 
   1129  1.1     kamil 		validate_status_exited(status, exitval2);
   1130  1.1     kamil 
   1131  1.1     kamil 		DPRINTF("Before calling %s() for the forkee - expected no process\n",
   1132  1.1     kamil 		    TWAIT_FNAME);
   1133  1.1     kamil 		TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(tracee2, &status, 0));
   1134  1.1     kamil 
   1135  1.1     kamil 		if (kill_process) {
   1136  1.1     kamil 			DPRINTF("Before calling %s() for the forkee - expected signaled\n",
   1137  1.1     kamil 			    TWAIT_FNAME);
   1138  1.1     kamil 			TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1139  1.1     kamil 
   1140  1.1     kamil 			validate_status_signaled(status, SIGKILL, 0);
   1141  1.1     kamil 		}
   1142  1.1     kamil 
   1143  1.1     kamil 		/* Inform parent that tracer is exiting normally */
   1144  1.1     kamil 		CHILD_TO_PARENT("tracer done", parent_tracer, msg);
   1145  1.1     kamil 
   1146  1.1     kamil 		DPRINTF("Before exiting of the tracer process\n");
   1147  1.1     kamil 		_exit(0 /* collect by initproc */);
   1148  1.1     kamil 	}
   1149  1.1     kamil 
   1150  1.1     kamil 	DPRINTF("Wait for the tracer process (direct child) to exit "
   1151  1.1     kamil 	    "calling %s()\n", TWAIT_FNAME);
   1152  1.1     kamil 	TWAIT_REQUIRE_SUCCESS(
   1153  1.1     kamil 	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
   1154  1.1     kamil 
   1155  1.1     kamil 	validate_status_exited(status, exitval);
   1156  1.1     kamil 
   1157  1.1     kamil 	DPRINTF("Wait for the non-exited tracee process with %s()\n",
   1158  1.1     kamil 	    TWAIT_FNAME);
   1159  1.1     kamil 	TWAIT_REQUIRE_SUCCESS(
   1160  1.1     kamil 	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
   1161  1.1     kamil 
   1162  1.1     kamil 	DPRINTF("Wait for the tracer to attach to the tracee\n");
   1163  1.1     kamil 	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
   1164  1.1     kamil 
   1165  1.1     kamil 	DPRINTF("Resume the tracee and let it crash\n");
   1166  1.1     kamil 	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
   1167  1.1     kamil 
   1168  1.1     kamil 	DPRINTF("Resume the tracer and let it detect crashed tracee\n");
   1169  1.1     kamil 	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
   1170  1.1     kamil 
   1171  1.1     kamil 	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
   1172  1.1     kamil 	    TWAIT_FNAME);
   1173  1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1174  1.1     kamil 
   1175  1.1     kamil 	if (kill_process) {
   1176  1.1     kamil 		validate_status_signaled(status, SIGKILL, 0);
   1177  1.1     kamil 	} else {
   1178  1.1     kamil 		validate_status_exited(status, exitval);
   1179  1.1     kamil 	}
   1180  1.1     kamil 
   1181  1.1     kamil 	DPRINTF("Await normal exit of tracer\n");
   1182  1.1     kamil 	PARENT_FROM_CHILD("tracer done", parent_tracer, msg);
   1183  1.1     kamil 
   1184  1.1     kamil 	msg_close(&parent_tracer);
   1185  1.1     kamil 	msg_close(&parent_tracee);
   1186  1.1     kamil }
   1187  1.1     kamil 
   1188  1.1     kamil #define UNRELATED_TRACER_FORK_DETACH_FORKER(name,event,kprocess)	\
   1189  1.1     kamil ATF_TC(name);								\
   1190  1.1     kamil ATF_TC_HEAD(name, tc)							\
   1191  1.1     kamil {									\
   1192  1.1     kamil 	atf_tc_set_md_var(tc, "descr", "Verify %s " event,		\
   1193  1.1     kamil 	    kprocess ? "killed" : "detached");				\
   1194  1.1     kamil }									\
   1195  1.1     kamil 									\
   1196  1.1     kamil ATF_TC_BODY(name, tc)							\
   1197  1.1     kamil {									\
   1198  1.1     kamil 									\
   1199  1.1     kamil 	unrelated_tracer_fork_detach_forker_body(event, kprocess);	\
   1200  1.1     kamil }
   1201  1.1     kamil 
   1202  1.1     kamil UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_posix_spawn_detach_spawner, "spawn", false)
   1203  1.1     kamil UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_fork_detach_forker, "fork", false)
   1204  1.1     kamil UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_detach_vforker, "vfork", false)
   1205  1.1     kamil UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_detach_vforkerdone, "vforkdone", false)
   1206  1.1     kamil 
   1207  1.1     kamil UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_posix_spawn_kill_spawner, "spawn", true)
   1208  1.1     kamil UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_fork_kill_forker, "fork", true)
   1209  1.1     kamil UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_kill_vforker, "vfork", true)
   1210  1.1     kamil UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_kill_vforkerdone, "vforkdone", true)
   1211  1.1     kamil #endif
   1212  1.1     kamil 
   1213  1.1     kamil /// ----------------------------------------------------------------------------
   1214  1.1     kamil 
   1215  1.1     kamil static void
   1216  1.1     kamil traceme_vfork_fork_body(pid_t (*fn)(void))
   1217  1.1     kamil {
   1218  1.1     kamil 	const int exitval = 5;
   1219  1.1     kamil 	const int exitval2 = 15;
   1220  1.1     kamil 	pid_t child, child2 = 0, wpid;
   1221  1.1     kamil #if defined(TWAIT_HAVE_STATUS)
   1222  1.1     kamil 	int status;
   1223  1.1     kamil #endif
   1224  1.1     kamil 
   1225  1.1     kamil 	DPRINTF("Before forking process PID=%d\n", getpid());
   1226  1.1     kamil 	SYSCALL_REQUIRE((child = vfork()) != -1);
   1227  1.1     kamil 	if (child == 0) {
   1228  1.1     kamil 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   1229  1.1     kamil 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   1230  1.1     kamil 
   1231  1.1     kamil 		FORKEE_ASSERT((child2 = (fn)()) != -1);
   1232  1.1     kamil 
   1233  1.1     kamil 		if (child2 == 0)
   1234  1.1     kamil 			_exit(exitval2);
   1235  1.1     kamil 
   1236  1.1     kamil 		FORKEE_REQUIRE_SUCCESS
   1237  1.1     kamil 		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
   1238  1.1     kamil 
   1239  1.1     kamil 		forkee_status_exited(status, exitval2);
   1240  1.1     kamil 
   1241  1.1     kamil 		DPRINTF("Before exiting of the child process\n");
   1242  1.1     kamil 		_exit(exitval);
   1243  1.1     kamil 	}
   1244  1.1     kamil 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   1245  1.1     kamil 
   1246  1.1     kamil 	DPRINTF("Before calling %s() for the child - expected exited\n",
   1247  1.1     kamil 	    TWAIT_FNAME);
   1248  1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1249  1.1     kamil 
   1250  1.1     kamil 	validate_status_exited(status, exitval);
   1251  1.1     kamil 
   1252  1.1     kamil 	DPRINTF("Before calling %s() for the child - expected no process\n",
   1253  1.1     kamil 	    TWAIT_FNAME);
   1254  1.1     kamil 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   1255  1.1     kamil }
   1256  1.1     kamil 
   1257  1.1     kamil #define TRACEME_VFORK_FORK_TEST(name,fun)				\
   1258  1.1     kamil ATF_TC(name);								\
   1259  1.1     kamil ATF_TC_HEAD(name, tc)							\
   1260  1.1     kamil {									\
   1261  1.1     kamil 	atf_tc_set_md_var(tc, "descr", "Verify " #fun "(2) "		\
   1262  1.1     kamil 	    "called from vfork(2)ed child");				\
   1263  1.1     kamil }									\
   1264  1.1     kamil 									\
   1265  1.1     kamil ATF_TC_BODY(name, tc)							\
   1266  1.1     kamil {									\
   1267  1.1     kamil 									\
   1268  1.1     kamil 	traceme_vfork_fork_body(fun);					\
   1269  1.1     kamil }
   1270  1.1     kamil 
   1271  1.1     kamil TRACEME_VFORK_FORK_TEST(traceme_vfork_fork, fork)
   1272  1.1     kamil TRACEME_VFORK_FORK_TEST(traceme_vfork_vfork, vfork)
   1273  1.1     kamil 
   1274  1.1     kamil /// ----------------------------------------------------------------------------
   1275  1.1     kamil 
   1276  1.1     kamil #if defined(TWAIT_HAVE_PID)
   1277  1.1     kamil static void
   1278  1.1     kamil fork2_body(const char *fn, bool masked, bool ignored)
   1279  1.1     kamil {
   1280  1.1     kamil 	const int exitval = 5;
   1281  1.1     kamil 	const int exitval2 = 0; /* Match exit status from /bin/echo */
   1282  1.1     kamil 	const int sigval = SIGSTOP;
   1283  1.1     kamil 	pid_t child, child2 = 0, wpid;
   1284  1.1     kamil #if defined(TWAIT_HAVE_STATUS)
   1285  1.1     kamil 	int status;
   1286  1.1     kamil #endif
   1287  1.1     kamil 	ptrace_state_t state;
   1288  1.1     kamil 	const int slen = sizeof(state);
   1289  1.1     kamil 	ptrace_event_t event;
   1290  1.1     kamil 	const int elen = sizeof(event);
   1291  1.1     kamil 	struct sigaction sa;
   1292  1.1     kamil 	struct ptrace_siginfo info;
   1293  1.1     kamil 	sigset_t intmask;
   1294  1.1     kamil 	struct kinfo_proc2 kp;
   1295  1.1     kamil 	size_t len = sizeof(kp);
   1296  1.1     kamil 
   1297  1.1     kamil 	int name[6];
   1298  1.1     kamil 	const size_t namelen = __arraycount(name);
   1299  1.4     kamil 	sigset_t set;
   1300  1.1     kamil 	ki_sigset_t kp_sigmask;
   1301  1.1     kamil 	ki_sigset_t kp_sigignore;
   1302  1.1     kamil 
   1303  1.1     kamil 	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
   1304  1.1     kamil 
   1305  1.1     kamil 	DPRINTF("Before forking process PID=%d\n", getpid());
   1306  1.1     kamil 	SYSCALL_REQUIRE((child = fork()) != -1);
   1307  1.1     kamil 	if (child == 0) {
   1308  1.1     kamil 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   1309  1.1     kamil 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   1310  1.1     kamil 
   1311  1.1     kamil 		if (masked) {
   1312  1.1     kamil 			sigemptyset(&intmask);
   1313  1.1     kamil 			sigaddset(&intmask, SIGTRAP);
   1314  1.1     kamil 			sigprocmask(SIG_BLOCK, &intmask, NULL);
   1315  1.1     kamil 		}
   1316  1.1     kamil 
   1317  1.1     kamil 		if (ignored) {
   1318  1.1     kamil 			memset(&sa, 0, sizeof(sa));
   1319  1.1     kamil 			sa.sa_handler = SIG_IGN;
   1320  1.1     kamil 			sigemptyset(&sa.sa_mask);
   1321  1.1     kamil 			FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1);
   1322  1.1     kamil 		}
   1323  1.1     kamil 
   1324  1.1     kamil 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
   1325  1.1     kamil 		FORKEE_ASSERT(raise(sigval) == 0);
   1326  1.1     kamil 
   1327  1.1     kamil 		if (strcmp(fn, "spawn") == 0) {
   1328  1.1     kamil 			FORKEE_ASSERT_EQ(posix_spawn(&child2,
   1329  1.1     kamil 			    arg[0], NULL, NULL, arg, NULL), 0);
   1330  1.1     kamil 		} else  {
   1331  1.1     kamil 			if (strcmp(fn, "fork") == 0) {
   1332  1.1     kamil 				FORKEE_ASSERT((child2 = fork()) != -1);
   1333  1.1     kamil 			} else {
   1334  1.1     kamil 				FORKEE_ASSERT((child2 = vfork()) != -1);
   1335  1.1     kamil 			}
   1336  1.1     kamil 			if (child2 == 0)
   1337  1.1     kamil 				_exit(exitval2);
   1338  1.1     kamil 		}
   1339  1.1     kamil 
   1340  1.1     kamil 		FORKEE_REQUIRE_SUCCESS
   1341  1.1     kamil 		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
   1342  1.1     kamil 
   1343  1.1     kamil 		forkee_status_exited(status, exitval2);
   1344  1.1     kamil 
   1345  1.1     kamil 		DPRINTF("Before exiting of the child process\n");
   1346  1.1     kamil 		_exit(exitval);
   1347  1.1     kamil 	}
   1348  1.1     kamil 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   1349  1.1     kamil 
   1350  1.1     kamil 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1351  1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1352  1.1     kamil 
   1353  1.1     kamil 	validate_status_stopped(status, sigval);
   1354  1.1     kamil 
   1355  1.1     kamil 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
   1356  1.1     kamil 	SYSCALL_REQUIRE(
   1357  1.1     kamil 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
   1358  1.1     kamil 
   1359  1.1     kamil 	DPRINTF("Before checking siginfo_t\n");
   1360  1.1     kamil 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
   1361  1.1     kamil 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
   1362  1.1     kamil 
   1363  1.1     kamil 	name[0] = CTL_KERN,
   1364  1.1     kamil 	name[1] = KERN_PROC2,
   1365  1.1     kamil 	name[2] = KERN_PROC_PID;
   1366  1.1     kamil 	name[3] = child;
   1367  1.1     kamil 	name[4] = sizeof(kp);
   1368  1.1     kamil 	name[5] = 1;
   1369  1.1     kamil 
   1370  1.1     kamil 	FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
   1371  1.1     kamil 
   1372  1.2     kamil 	kp_sigmask = kp.p_sigmask;
   1373  1.2     kamil 	kp_sigignore = kp.p_sigignore;
   1374  1.1     kamil 
   1375  1.1     kamil 	DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n",
   1376  1.1     kamil 	    strcmp(fn, "spawn") == 0 ? "|PTRACE_POSIX_SPAWN" : "",
   1377  1.1     kamil 	    strcmp(fn, "fork") == 0 ? "|PTRACE_FORK" : "",
   1378  1.1     kamil 	    strcmp(fn, "vfork") == 0 ? "|PTRACE_VFORK" : "",
   1379  1.1     kamil 	    strcmp(fn, "vforkdone") == 0 ? "|PTRACE_VFORK_DONE" : "", child);
   1380  1.1     kamil 	event.pe_set_event = 0;
   1381  1.1     kamil 	if (strcmp(fn, "spawn") == 0)
   1382  1.1     kamil 		event.pe_set_event |= PTRACE_POSIX_SPAWN;
   1383  1.1     kamil 	if (strcmp(fn, "fork") == 0)
   1384  1.1     kamil 		event.pe_set_event |= PTRACE_FORK;
   1385  1.1     kamil 	if (strcmp(fn, "vfork") == 0)
   1386  1.1     kamil 		event.pe_set_event |= PTRACE_VFORK;
   1387  1.1     kamil 	if (strcmp(fn, "vforkdone") == 0)
   1388  1.1     kamil 		event.pe_set_event |= PTRACE_VFORK_DONE;
   1389  1.1     kamil 	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
   1390  1.1     kamil 
   1391  1.4     kamil 	/*
   1392  1.4     kamil 	 * Ignore interception of the SIGCHLD signals.
   1393  1.4     kamil 	 *
   1394  1.4     kamil 	 * SIGCHLD once blocked is discarded by the kernel as it has the
   1395  1.4     kamil 	 * SA_IGNORE property. During the fork(2) operation all signals can be
   1396  1.4     kamil 	 * shortly blocked and missed (unless there is a registered signal
   1397  1.4     kamil 	 * handler in the traced child). This leads to a race in this test if
   1398  1.4     kamil 	 * there would be an intention to catch SIGCHLD.
   1399  1.4     kamil 	 */
   1400  1.4     kamil 	sigemptyset(&set);
   1401  1.4     kamil 	sigaddset(&set, SIGCHLD);
   1402  1.4     kamil 	SYSCALL_REQUIRE(ptrace(PT_SET_SIGPASS, child, &set, sizeof(set)) != -1);
   1403  1.4     kamil 
   1404  1.1     kamil 	DPRINTF("Before resuming the child process where it left off and "
   1405  1.1     kamil 	    "without signal to be sent\n");
   1406  1.1     kamil 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   1407  1.1     kamil 
   1408  1.1     kamil 	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
   1409  1.1     kamil 	    strcmp(fn, "vfork") == 0) {
   1410  1.1     kamil 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
   1411  1.1     kamil 		    child);
   1412  1.1     kamil 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
   1413  1.1     kamil 		    child);
   1414  1.1     kamil 
   1415  1.1     kamil 		validate_status_stopped(status, SIGTRAP);
   1416  1.1     kamil 
   1417  1.1     kamil 		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
   1418  1.1     kamil 
   1419  1.1     kamil 		if (masked) {
   1420  1.1     kamil 			DPRINTF("kp_sigmask="
   1421  1.1     kamil 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1422  1.1     kamil 			    PRIx32 "\n",
   1423  1.1     kamil 			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
   1424  1.1     kamil 			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
   1425  1.1     kamil 
   1426  1.1     kamil 			DPRINTF("kp.p_sigmask="
   1427  1.1     kamil 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1428  1.1     kamil 			    PRIx32 "\n",
   1429  1.1     kamil 			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
   1430  1.1     kamil 			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
   1431  1.1     kamil 
   1432  1.2     kamil 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigmask,
   1433  1.2     kamil 			    SIGTRAP));
   1434  1.1     kamil 		}
   1435  1.1     kamil 
   1436  1.1     kamil 		if (ignored) {
   1437  1.1     kamil 			DPRINTF("kp_sigignore="
   1438  1.1     kamil 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1439  1.1     kamil 			    PRIx32 "\n",
   1440  1.1     kamil 			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
   1441  1.1     kamil 			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
   1442  1.1     kamil 
   1443  1.1     kamil 			DPRINTF("kp.p_sigignore="
   1444  1.1     kamil 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1445  1.1     kamil 			    PRIx32 "\n",
   1446  1.1     kamil 			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
   1447  1.1     kamil 			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
   1448  1.1     kamil 
   1449  1.2     kamil 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigignore,
   1450  1.2     kamil 			    SIGTRAP));
   1451  1.1     kamil 		}
   1452  1.1     kamil 
   1453  1.1     kamil 		SYSCALL_REQUIRE(
   1454  1.1     kamil 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
   1455  1.1     kamil 		if (strcmp(fn, "spawn") == 0) {
   1456  1.1     kamil 			ATF_REQUIRE_EQ(
   1457  1.1     kamil 			    state.pe_report_event & PTRACE_POSIX_SPAWN,
   1458  1.1     kamil 			       PTRACE_POSIX_SPAWN);
   1459  1.1     kamil 		}
   1460  1.1     kamil 		if (strcmp(fn, "fork") == 0) {
   1461  1.1     kamil 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
   1462  1.1     kamil 			       PTRACE_FORK);
   1463  1.1     kamil 		}
   1464  1.1     kamil 		if (strcmp(fn, "vfork") == 0) {
   1465  1.1     kamil 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
   1466  1.1     kamil 			       PTRACE_VFORK);
   1467  1.1     kamil 		}
   1468  1.1     kamil 
   1469  1.1     kamil 		child2 = state.pe_other_pid;
   1470  1.1     kamil 		DPRINTF("Reported ptrace event with forkee %d\n", child2);
   1471  1.1     kamil 
   1472  1.1     kamil 		DPRINTF("Before calling %s() for the forkee %d of the child "
   1473  1.1     kamil 		    "%d\n", TWAIT_FNAME, child2, child);
   1474  1.1     kamil 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
   1475  1.1     kamil 		    child2);
   1476  1.1     kamil 
   1477  1.1     kamil 		validate_status_stopped(status, SIGTRAP);
   1478  1.1     kamil 
   1479  1.1     kamil 		name[3] = child2;
   1480  1.1     kamil 		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
   1481  1.1     kamil 
   1482  1.1     kamil 		if (masked) {
   1483  1.1     kamil 			DPRINTF("kp_sigmask="
   1484  1.1     kamil 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1485  1.1     kamil 			    PRIx32 "\n",
   1486  1.1     kamil 			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
   1487  1.1     kamil 			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
   1488  1.1     kamil 
   1489  1.1     kamil 			DPRINTF("kp.p_sigmask="
   1490  1.1     kamil 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1491  1.1     kamil 			    PRIx32 "\n",
   1492  1.1     kamil 			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
   1493  1.1     kamil 			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
   1494  1.1     kamil 
   1495  1.2     kamil 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigmask,
   1496  1.2     kamil 			    SIGTRAP));
   1497  1.1     kamil 		}
   1498  1.1     kamil 
   1499  1.1     kamil 		if (ignored) {
   1500  1.1     kamil 			DPRINTF("kp_sigignore="
   1501  1.1     kamil 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1502  1.1     kamil 			    PRIx32 "\n",
   1503  1.1     kamil 			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
   1504  1.1     kamil 			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
   1505  1.1     kamil 
   1506  1.1     kamil 			DPRINTF("kp.p_sigignore="
   1507  1.1     kamil 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1508  1.1     kamil 			    PRIx32 "\n",
   1509  1.1     kamil 			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
   1510  1.1     kamil 			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
   1511  1.1     kamil 
   1512  1.2     kamil 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigignore,
   1513  1.2     kamil 			    SIGTRAP));
   1514  1.1     kamil 		}
   1515  1.1     kamil 
   1516  1.1     kamil 		SYSCALL_REQUIRE(
   1517  1.1     kamil 		    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
   1518  1.1     kamil 		if (strcmp(fn, "spawn") == 0) {
   1519  1.1     kamil 			ATF_REQUIRE_EQ(
   1520  1.1     kamil 			    state.pe_report_event & PTRACE_POSIX_SPAWN,
   1521  1.1     kamil 			       PTRACE_POSIX_SPAWN);
   1522  1.1     kamil 		}
   1523  1.1     kamil 		if (strcmp(fn, "fork") == 0) {
   1524  1.1     kamil 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
   1525  1.1     kamil 			       PTRACE_FORK);
   1526  1.1     kamil 		}
   1527  1.1     kamil 		if (strcmp(fn, "vfork") == 0) {
   1528  1.1     kamil 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
   1529  1.1     kamil 			       PTRACE_VFORK);
   1530  1.1     kamil 		}
   1531  1.1     kamil 
   1532  1.1     kamil 		ATF_REQUIRE_EQ(state.pe_other_pid, child);
   1533  1.1     kamil 
   1534  1.1     kamil 		DPRINTF("Before resuming the forkee process where it left off "
   1535  1.1     kamil 		    "and without signal to be sent\n");
   1536  1.1     kamil 		SYSCALL_REQUIRE(
   1537  1.1     kamil 		    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
   1538  1.1     kamil 
   1539  1.1     kamil 		DPRINTF("Before resuming the child process where it left off "
   1540  1.1     kamil 		    "and without signal to be sent\n");
   1541  1.1     kamil 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   1542  1.1     kamil 	}
   1543  1.1     kamil 
   1544  1.1     kamil 	if (strcmp(fn, "vforkdone") == 0) {
   1545  1.1     kamil 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
   1546  1.1     kamil 		    child);
   1547  1.1     kamil 		TWAIT_REQUIRE_SUCCESS(
   1548  1.1     kamil 		    wpid = TWAIT_GENERIC(child, &status, 0), child);
   1549  1.1     kamil 
   1550  1.1     kamil 		validate_status_stopped(status, SIGTRAP);
   1551  1.1     kamil 
   1552  1.1     kamil 		name[3] = child;
   1553  1.1     kamil 		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
   1554  1.1     kamil 
   1555  1.1     kamil 		/*
   1556  1.1     kamil 		 * SIGCHLD is now pending in the signal queue and
   1557  1.1     kamil 		 * the kernel presents it to userland as a masked signal.
   1558  1.1     kamil 		 */
   1559  1.1     kamil 		sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD);
   1560  1.1     kamil 
   1561  1.1     kamil 		if (masked) {
   1562  1.1     kamil 			DPRINTF("kp_sigmask="
   1563  1.1     kamil 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1564  1.1     kamil 			    PRIx32 "\n",
   1565  1.1     kamil 			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
   1566  1.1     kamil 			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
   1567  1.1     kamil 
   1568  1.1     kamil 			DPRINTF("kp.p_sigmask="
   1569  1.1     kamil 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1570  1.1     kamil 			    PRIx32 "\n",
   1571  1.1     kamil 			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
   1572  1.1     kamil 			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
   1573  1.1     kamil 
   1574  1.2     kamil 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigmask,
   1575  1.2     kamil 			    SIGTRAP));
   1576  1.1     kamil 		}
   1577  1.1     kamil 
   1578  1.1     kamil 		if (ignored) {
   1579  1.1     kamil 			DPRINTF("kp_sigignore="
   1580  1.1     kamil 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1581  1.1     kamil 			    PRIx32 "\n",
   1582  1.1     kamil 			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
   1583  1.1     kamil 			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
   1584  1.1     kamil 
   1585  1.1     kamil 			DPRINTF("kp.p_sigignore="
   1586  1.1     kamil 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1587  1.1     kamil 			    PRIx32 "\n",
   1588  1.1     kamil 			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
   1589  1.1     kamil 			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
   1590  1.1     kamil 
   1591  1.2     kamil 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigignore,
   1592  1.2     kamil 			    SIGTRAP));
   1593  1.1     kamil 		}
   1594  1.1     kamil 
   1595  1.1     kamil 		SYSCALL_REQUIRE(
   1596  1.1     kamil 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
   1597  1.1     kamil 		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
   1598  1.1     kamil 
   1599  1.1     kamil 		child2 = state.pe_other_pid;
   1600  1.1     kamil 		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
   1601  1.1     kamil 		    child2);
   1602  1.1     kamil 
   1603  1.1     kamil 		DPRINTF("Before resuming the child process where it left off "
   1604  1.1     kamil 		    "and without signal to be sent\n");
   1605  1.1     kamil 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   1606  1.1     kamil 	}
   1607  1.1     kamil 
   1608  1.1     kamil 	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
   1609  1.1     kamil 	    strcmp(fn, "vfork") == 0) {
   1610  1.1     kamil 		DPRINTF("Before calling %s() for the forkee - expected exited"
   1611  1.1     kamil 		    "\n", TWAIT_FNAME);
   1612  1.1     kamil 		TWAIT_REQUIRE_SUCCESS(
   1613  1.1     kamil 		    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
   1614  1.1     kamil 
   1615  1.1     kamil 		validate_status_exited(status, exitval2);
   1616  1.1     kamil 
   1617  1.1     kamil 		DPRINTF("Before calling %s() for the forkee - expected no "
   1618  1.1     kamil 		    "process\n", TWAIT_FNAME);
   1619  1.1     kamil 		TWAIT_REQUIRE_FAILURE(ECHILD,
   1620  1.1     kamil 		    wpid = TWAIT_GENERIC(child2, &status, 0));
   1621  1.1     kamil 	}
   1622  1.1     kamil 
   1623  1.1     kamil 	DPRINTF("Before calling %s() for the child - expected exited\n",
   1624  1.1     kamil 	    TWAIT_FNAME);
   1625  1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1626  1.1     kamil 
   1627  1.1     kamil 	validate_status_exited(status, exitval);
   1628  1.1     kamil 
   1629  1.1     kamil 	DPRINTF("Before calling %s() for the child - expected no process\n",
   1630  1.1     kamil 	    TWAIT_FNAME);
   1631  1.1     kamil 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   1632  1.1     kamil }
   1633  1.1     kamil 
   1634  1.1     kamil #define FORK2_TEST(name,fn,masked,ignored)				\
   1635  1.1     kamil ATF_TC(name);								\
   1636  1.1     kamil ATF_TC_HEAD(name, tc)							\
   1637  1.1     kamil {									\
   1638  1.1     kamil 	atf_tc_set_md_var(tc, "descr", "Verify that " fn " is caught "	\
   1639  1.1     kamil 	    "regardless of signal %s%s", 				\
   1640  1.1     kamil 	    masked ? "masked" : "", ignored ? "ignored" : "");		\
   1641  1.1     kamil }									\
   1642  1.1     kamil 									\
   1643  1.1     kamil ATF_TC_BODY(name, tc)							\
   1644  1.1     kamil {									\
   1645  1.1     kamil 									\
   1646  1.1     kamil 	fork2_body(fn, masked, ignored);				\
   1647  1.1     kamil }
   1648  1.1     kamil 
   1649  1.5     kamil FORK2_TEST(posix_spawn_signalmasked, "spawn", true, false)
   1650  1.5     kamil FORK2_TEST(posix_spawn_signalignored, "spawn", false, true)
   1651  1.5     kamil FORK2_TEST(fork_signalmasked, "fork", true, false)
   1652  1.5     kamil FORK2_TEST(fork_signalignored, "fork", false, true)
   1653  1.5     kamil FORK2_TEST(vfork_signalmasked, "vfork", true, false)
   1654  1.5     kamil FORK2_TEST(vfork_signalignored, "vfork", false, true)
   1655  1.5     kamil FORK2_TEST(vforkdone_signalmasked, "vforkdone", true, false)
   1656  1.5     kamil FORK2_TEST(vforkdone_signalignored, "vforkdone", false, true)
   1657  1.1     kamil #endif
   1658  1.1     kamil 
   1659  1.1     kamil #define ATF_TP_ADD_TCS_PTRACE_WAIT_FORK() \
   1660  1.1     kamil 	ATF_TP_ADD_TC(tp, fork1); \
   1661  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork2); \
   1662  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork3); \
   1663  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork4); \
   1664  1.1     kamil 	ATF_TP_ADD_TC(tp, fork5); \
   1665  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork6); \
   1666  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork7); \
   1667  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork8); \
   1668  1.1     kamil 	ATF_TP_ADD_TC(tp, fork9); \
   1669  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork10); \
   1670  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork11); \
   1671  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork12); \
   1672  1.1     kamil 	ATF_TP_ADD_TC(tp, fork13); \
   1673  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork14); \
   1674  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork15); \
   1675  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork16); \
   1676  1.7     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_setpgid); \
   1677  1.1     kamil 	ATF_TP_ADD_TC(tp, vfork1); \
   1678  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); \
   1679  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); \
   1680  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); \
   1681  1.1     kamil 	ATF_TP_ADD_TC(tp, vfork5); \
   1682  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); \
   1683  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); \
   1684  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); \
   1685  1.1     kamil 	ATF_TP_ADD_TC(tp, vfork9); \
   1686  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork10); \
   1687  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork11); \
   1688  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork12); \
   1689  1.1     kamil 	ATF_TP_ADD_TC(tp, vfork13); \
   1690  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork14); \
   1691  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork15); \
   1692  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork16); \
   1693  1.7     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_setpgid); \
   1694  1.1     kamil 	ATF_TP_ADD_TC(tp, posix_spawn1); \
   1695  1.1     kamil 	ATF_TP_ADD_TC(tp, posix_spawn2); \
   1696  1.1     kamil 	ATF_TP_ADD_TC(tp, posix_spawn3); \
   1697  1.1     kamil 	ATF_TP_ADD_TC(tp, posix_spawn4); \
   1698  1.1     kamil 	ATF_TP_ADD_TC(tp, posix_spawn5); \
   1699  1.1     kamil 	ATF_TP_ADD_TC(tp, posix_spawn6); \
   1700  1.1     kamil 	ATF_TP_ADD_TC(tp, posix_spawn7); \
   1701  1.1     kamil 	ATF_TP_ADD_TC(tp, posix_spawn8); \
   1702  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn9); \
   1703  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn10); \
   1704  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn11); \
   1705  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn12); \
   1706  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn13); \
   1707  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn14); \
   1708  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn15); \
   1709  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn16); \
   1710  1.7     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_setpgid); \
   1711  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork1); \
   1712  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork2); \
   1713  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork3); \
   1714  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork4); \
   1715  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork5); \
   1716  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork6); \
   1717  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork7); \
   1718  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork8); \
   1719  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork9); \
   1720  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork10); \
   1721  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork11); \
   1722  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork12); \
   1723  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork13); \
   1724  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork14); \
   1725  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork15); \
   1726  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork16); \
   1727  1.7     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_setpgid); \
   1728  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork1); \
   1729  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork2); \
   1730  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork3); \
   1731  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork4); \
   1732  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork5); \
   1733  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork6); \
   1734  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork7); \
   1735  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork8); \
   1736  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork9); \
   1737  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork10); \
   1738  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork11); \
   1739  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork12); \
   1740  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork13); \
   1741  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork14); \
   1742  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork15); \
   1743  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork16); \
   1744  1.7     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_setpgid); \
   1745  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn1); \
   1746  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn2); \
   1747  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn3); \
   1748  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn4); \
   1749  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn5); \
   1750  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn6); \
   1751  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn7); \
   1752  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn8); \
   1753  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn9); \
   1754  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn10); \
   1755  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn11); \
   1756  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn12); \
   1757  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn13); \
   1758  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn14); \
   1759  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn15); \
   1760  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn16); \
   1761  1.7     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_setpgid); \
   1762  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_detach_spawner); \
   1763  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_detach_forker); \
   1764  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforker); \
   1765  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforkerdone); \
   1766  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_kill_spawner); \
   1767  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_kill_forker); \
   1768  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforker); \
   1769  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforkerdone); \
   1770  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_detach_spawner); \
   1771  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_detach_forker); \
   1772  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_detach_vforker); \
   1773  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_detach_vforkerdone); \
   1774  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_kill_spawner); \
   1775  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_kill_forker); \
   1776  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_kill_vforker); \
   1777  1.1     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_kill_vforkerdone); \
   1778  1.1     kamil 	ATF_TP_ADD_TC(tp, traceme_vfork_fork); \
   1779  1.1     kamil 	ATF_TP_ADD_TC(tp, traceme_vfork_vfork); \
   1780  1.5     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_signalmasked); \
   1781  1.5     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_signalignored); \
   1782  1.5     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_signalmasked); \
   1783  1.5     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_signalignored); \
   1784  1.5     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_signalmasked); \
   1785  1.5     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_signalignored); \
   1786  1.5     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_signalmasked); \
   1787  1.5     kamil 	ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_signalignored);
   1788