Module Name:    src
Committed By:   kamil
Date:           Sat Apr  6 15:41:54 UTC 2019

Modified Files:
        src/tests/lib/libc/sys: t_fork.c

Log Message:
Add new tests in ATF t_fork/t_vfork

Verify whether nested fork(2)/vfork(2)/clone(2) calls are supported in a
fork(2)ed/vforked(2) child.

The interesting ones are non-forked parent and non-forked child scenarios,
in particular double vfork(2).


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/tests/lib/libc/sys/t_fork.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/lib/libc/sys/t_fork.c
diff -u src/tests/lib/libc/sys/t_fork.c:1.3 src/tests/lib/libc/sys/t_fork.c:1.4
--- src/tests/lib/libc/sys/t_fork.c:1.3	Sat May 19 05:10:16 2018
+++ src/tests/lib/libc/sys/t_fork.c	Sat Apr  6 15:41:54 2019
@@ -1,7 +1,7 @@
-/*	$NetBSD: t_fork.c,v 1.3 2018/05/19 05:10:16 kamil Exp $	*/
+/*	$NetBSD: t_fork.c,v 1.4 2019/04/06 15:41:54 kamil Exp $	*/
 
 /*-
- * Copyright (c) 2018 The NetBSD Foundation, Inc.
+ * Copyright (c) 2018, 2019 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,15 +27,17 @@
  */
 
 #include <sys/cdefs.h>
-__COPYRIGHT("@(#) Copyright (c) 2018\
+__COPYRIGHT("@(#) Copyright (c) 2018, 2019\
  The NetBSD Foundation, inc. All rights reserved.");
-__RCSID("$NetBSD: t_fork.c,v 1.3 2018/05/19 05:10:16 kamil Exp $");
+__RCSID("$NetBSD: t_fork.c,v 1.4 2019/04/06 15:41:54 kamil Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/sysctl.h>
 #include <sys/wait.h>
+#include <sched.h>
 #include <signal.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <err.h>
@@ -242,7 +244,7 @@ ATF_TC_HEAD(test, tc)								\
 {										\
 										\
 	atf_tc_set_md_var(tc, "descr",						\
-	    "raise " #sig " in vfork(2)ed child");				\
+	    "raise " #sig " in a child");					\
 }										\
 										\
 ATF_TC_BODY(test, tc)								\
@@ -260,6 +262,97 @@ RAISE(raise6, SIGABRT) /* regular abort 
 RAISE(raise7, SIGHUP)  /* hangup */
 RAISE(raise8, SIGCONT) /* continued? */
 
+/// ----------------------------------------------------------------------------
+
+static int
+clone_func(void *arg __unused)
+{
+
+	return 0;
+}
+
+static void
+nested_raw(const char *fn, volatile int flags)
+{
+	int status;
+	pid_t child, child2, wpid;
+	const size_t stack_size = 1024 * 1024;
+	void *stack, *stack_base;
+                
+	stack = malloc(stack_size);
+	ATF_REQUIRE(stack != NULL);
+
+#ifdef __MACHINE_STACK_GROWS_UP
+	stack_base = stack;
+#else
+	stack_base = (char *)stack + stack_size;
+#endif
+
+	flags |= SIGCHLD;
+
+	child = FORK();
+	ATF_REQUIRE(child != 1);
+	if (child == 0) {
+		if (strcmp(fn, "fork") == 0)
+			child2 = fork();
+		else if (strcmp(fn, "vfork") == 0)
+			child2 = vfork();
+		else if (strcmp(fn, "clone") == 0)
+			child2 = __clone(clone_func, stack_base, flags, NULL);
+		else
+			__unreachable();
+
+		ASSERT_NEQ(child2, -1);
+
+		if ((strcmp(fn, "fork") == 0) || (strcmp(fn, "vfork") == 0)) {
+			if (child2 == 0)
+				_exit(0);
+		}
+
+		wpid = waitpid(child2, &status, 0);
+		ASSERT_EQ(child2, wpid);
+		ASSERT_EQ(!!WIFEXITED(status), true);
+		ASSERT_EQ(!!WIFCONTINUED(status), false);
+		ASSERT_EQ(!!WIFSIGNALED(status), false);
+		ASSERT_EQ(!!WIFSTOPPED(status), false);
+		ASSERT_EQ(WEXITSTATUS(status), 0);
+
+		_exit(0);
+	}
+	wpid = waitpid(child, &status, 0);
+
+	ATF_REQUIRE_EQ(wpid, child);
+	ATF_REQUIRE_EQ(!!WIFEXITED(status), true);
+	ATF_REQUIRE_EQ(!!WIFCONTINUED(status), false);
+	ATF_REQUIRE_EQ(!!WIFSIGNALED(status), false);
+	ATF_REQUIRE_EQ(!!WIFSTOPPED(status), false);
+	ATF_REQUIRE_EQ(WEXITSTATUS(status), 0);
+}
+
+#define NESTED(test, fn, flags)							\
+ATF_TC(test);									\
+ATF_TC_HEAD(test, tc)								\
+{										\
+										\
+	atf_tc_set_md_var(tc, "descr",						\
+	    "Test nested " #fn " in a child");					\
+}										\
+										\
+ATF_TC_BODY(test, tc)								\
+{										\
+										\
+	nested_raw(#fn, flags);							\
+}
+
+NESTED(nested_fork, fork, 0)
+NESTED(nested_vfork, vfork, 0)
+NESTED(nested_clone, clone, 0)
+NESTED(nested_clone_vm, clone, CLONE_VM)
+NESTED(nested_clone_fs, clone, CLONE_FS)
+NESTED(nested_clone_files, clone, CLONE_FILES)
+//NESTED(nested_clone_sighand, clone, CLONE_SIGHAND) // XXX
+NESTED(nested_clone_vfork, clone, CLONE_VFORK)
+
 ATF_TP_ADD_TCS(tp)
 {
 	ATF_TP_ADD_TC(tp, raise1);
@@ -271,5 +364,14 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC(tp, raise7);
 	ATF_TP_ADD_TC(tp, raise8);
 
+	ATF_TP_ADD_TC(tp, nested_fork);
+	ATF_TP_ADD_TC(tp, nested_vfork);
+	ATF_TP_ADD_TC(tp, nested_clone);
+	ATF_TP_ADD_TC(tp, nested_clone_vm);
+	ATF_TP_ADD_TC(tp, nested_clone_fs);
+	ATF_TP_ADD_TC(tp, nested_clone_files);
+//	ATF_TP_ADD_TC(tp, nested_clone_sighand); // XXX
+	ATF_TP_ADD_TC(tp, nested_clone_vfork);
+
 	return atf_no_error();
 }

Reply via email to