All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] waitpid: new API
@ 2016-07-15 14:39 Stanislav Kholmanskikh
  2016-07-15 14:39 ` [LTP] [PATCH 1/8] tst_safe_macros: SAFE_GETPGID Stanislav Kholmanskikh
                   ` (7 more replies)
  0 siblings, 8 replies; 24+ messages in thread
From: Stanislav Kholmanskikh @ 2016-07-15 14:39 UTC (permalink / raw)
  To: ltp

Hi!

This series is a continuation of [1], i.e. I converted those waitpid*
test cases utilizing wait_for_parent() to use the checkpoint interface
(along with the new test API).

The main difference from [1] is that I moved duplicated code to
a common header.

The only unconverted test case is waitpid10. It needs some more time.

Thanks.

[1] http://lists.linux.it/pipermail/ltp/2016-July/002178.html



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 1/8] tst_safe_macros: SAFE_GETPGID
  2016-07-15 14:39 [LTP] waitpid: new API Stanislav Kholmanskikh
@ 2016-07-15 14:39 ` Stanislav Kholmanskikh
  2016-07-15 14:39 ` [LTP] [PATCH 2/8] waitpid06: use the new API Stanislav Kholmanskikh
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 24+ messages in thread
From: Stanislav Kholmanskikh @ 2016-07-15 14:39 UTC (permalink / raw)
  To: ltp

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
 include/tst_safe_macros.h |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/include/tst_safe_macros.h b/include/tst_safe_macros.h
index 540fcb2..3cf154e 100644
--- a/include/tst_safe_macros.h
+++ b/include/tst_safe_macros.h
@@ -135,6 +135,22 @@ static inline int safe_setpgid(const char *file, const int lineno,
 #define SAFE_SETPGID(pid, pgid) \
 	safe_setpgid(__FILE__, __LINE__, (pid), (pgid));
 
+static inline pid_t safe_getpgid(const char *file, const int lineno,
+				 pid_t pid)
+{
+	pid_t pgid;
+
+	pgid = getpgid(pid);
+	if (pgid == -1) {
+		tst_brk_(file, lineno, TBROK | TERRNO,
+			 "getpgid(%i) failed", pid);
+	}
+
+	return pgid;
+}
+#define SAFE_GETPGID(pid) \
+	safe_getpgid(__FILE__, __LINE__, (pid))
+
 #define SAFE_UNLINK(pathname) \
 	safe_unlink(__FILE__, __LINE__, NULL, (pathname))
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 2/8] waitpid06: use the new API
  2016-07-15 14:39 [LTP] waitpid: new API Stanislav Kholmanskikh
  2016-07-15 14:39 ` [LTP] [PATCH 1/8] tst_safe_macros: SAFE_GETPGID Stanislav Kholmanskikh
@ 2016-07-15 14:39 ` Stanislav Kholmanskikh
  2016-07-18 13:05   ` Cyril Hrubis
  2016-07-15 14:39 ` [LTP] [PATCH 3/8] waitpid07: " Stanislav Kholmanskikh
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 24+ messages in thread
From: Stanislav Kholmanskikh @ 2016-07-15 14:39 UTC (permalink / raw)
  To: ltp

 * Use the new LTP API
 * Use the checkpoint interface instead of wait_for_parent()
 * Drop UCLINUX support

Common items were moved to a header file.

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
 testcases/kernel/syscalls/waitpid/waitpid06.c      |  264 ++++----------------
 testcases/kernel/syscalls/waitpid/waitpid_common.h |   78 ++++++
 2 files changed, 121 insertions(+), 221 deletions(-)
 create mode 100644 testcases/kernel/syscalls/waitpid/waitpid_common.h

diff --git a/testcases/kernel/syscalls/waitpid/waitpid06.c b/testcases/kernel/syscalls/waitpid/waitpid06.c
index dbbc104..be3d8e2 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid06.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid06.c
@@ -1,204 +1,60 @@
 /*
+ * Copyright (c) International Business Machines  Corp., 2001
  *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * This program is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
  *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * History
+ *	07/2001 John George
+ *		-Ported
+ *      04/2002 wjhuie sigset cleanups
  */
 
 /*
- * NAME
- *	waitpid06.c
- *
  * DESCRIPTION
- *	Tests to see if pid's returned from fork and waitpid are same.
+ *	Tests to see if pids returned from fork and waitpid are same.
  *
  * ALGORITHM
  *	Check proper functioning of waitpid with pid = -1 and arg = 0
- *
- * USAGE:  <for command-line>
- *      waitpid06 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- *      where,  -c n : Run n copies concurrently.
- *              -e   : Turn on errno logging.
- *              -i n : Execute test n times.
- *              -I x : Execute test for x seconds.
- *              -P x : Pause for x seconds between iterations.
- *              -t   : Turn on syscall timing.
- *
- * History
- *	07/2001 John George
- *		-Ported
- *      04/2002 wjhuie sigset cleanups
- *
- * Restrictions
- *	None
  */
 
-#include <sys/types.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include "test.h"
-
-static void setup_sigint(void);
-static void do_child_1(void);
-static void setup(void);
-static void cleanup(void);
-
-char *TCID = "waitpid06";
-int TST_TOTAL = 1;
-volatile int intintr;
-static void inthandlr();
-static void do_exit(void);
-static int flag;
-
-#define	FAILED	1
-#define	MAXKIDS	8
-
-#ifdef UCLINUX
-static char *argv0;
-static void do_child_2_uclinux(void);
-#endif
-
-int main(int argc, char **argv)
-{
-	int lc;
-	int fail = 0;
-	int pid;
-	int status;
-
-	tst_parse_opts(argc, argv, NULL, NULL);
-
-#ifdef UCLINUX
-	argv0 = argv[0];
-
-	maybe_run_child(&do_child_1, "n", 1);
-	maybe_run_child(&do_child_2_uclinux, "n", 2);
-#endif
-
-	setup();
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		pid = FORK_OR_VFORK();
-		if (pid < 0) {
-			tst_resm(TINFO, "Fork Failed, may be OK under stress");
-			exit(pid);
-		} else if (pid == 0) {
-			/*
-			 * Child:
-			 * Set up to catch SIGINT.  The kids will wait till a
-			 * SIGINT has been received before they proceed.
-			 */
-#ifdef UCLINUX
-			if (self_exec(argv[0], "n", 1) < 0) {
-				tst_resm(TINFO, "self_exec failed");
-				exit(pid);
-			}
-#else
-			do_child_1();
-#endif
-		} else {	/* parent */
-			fail = 0;
-			waitpid(pid, &status, 0);
-			if (WEXITSTATUS(status) != 0) {
-				tst_resm(TFAIL, "child returned bad status");
-				fail = 1;
-			}
-			if (fail)
-				tst_resm(TFAIL, "%s FAILED", TCID);
-			else
-				tst_resm(TPASS, "%s PASSED", TCID);
-		}
-	}
-
-	cleanup();
-	tst_exit();
-}
-
-/*
- * setup_sigint()
- *	Sets up a SIGINT handler
- */
-static void setup_sigint(void)
-{
-	if ((sig_t) signal(SIGINT, inthandlr) == SIG_ERR) {
-		tst_resm(TFAIL, "signal SIGINT failed. " "errno = %d", errno);
-		exit(-1);
-	}
-}
+#include "waitpid_common.h"
 
 static void do_child_1(void)
 {
-	int kid_count, fork_kid_pid[MAXKIDS];
-	int ret_val;
+	int kid_count;
+	pid_t ret_val;
 	int i, j, k, found;
-	int group1, group2;
-	int wait_kid_pid[MAXKIDS], status;
-
-	setup_sigint();
+	pid_t wait_kid_pid[MAXKIDS];
+	int status;
+	int flag = 0;
 
-	group1 = getpgrp();
 	for (kid_count = 0; kid_count < MAXKIDS; kid_count++) {
 		if (kid_count == (MAXKIDS / 2))
-			group2 = setpgrp();
+			SAFE_SETPGID(0, 0);
 
-		intintr = 0;
-		ret_val = FORK_OR_VFORK();
-		if (ret_val == 0) {	/* child */
-#ifdef UCLINUX
-			if (self_exec(argv0, "n", 2) < 0) {
-				tst_resm(TFAIL, "Fork kid %d failed. "
-					 "errno = %d", kid_count, errno);
-				exit(ret_val);
-			}
-#else
-			do_exit();
-#endif
-		} else if (ret_val < 0) {
-			tst_resm(TFAIL, "Fork kid %d failed. "
-				 "errno = %d", kid_count, errno);
-			exit(ret_val);
-		}
+		ret_val = SAFE_FORK();
+		if (ret_val == 0)
+			do_exit(0);
 
-		/* parent */
 		fork_kid_pid[kid_count] = ret_val;
 	}
 
-#ifdef UCLINUX
-	/* Give the kids a chance to setup SIGINT again, since this is
-	 * cleared by exec().
-	 */
-	sleep(3);
-#endif
-
-	/* Now send all the kids a SIGINT to tell them to
-	 * proceed
-	 */
-	for (i = 0; i < MAXKIDS; i++) {
-		if (kill(fork_kid_pid[i], SIGINT) < 0) {
-			tst_resm(TFAIL, "Kill of child %d "
-				 "failed, errno = %d", i, errno);
-			exit(-1);
-		}
-	}
+	TST_CHECKPOINT_WAKE2(0, MAXKIDS);
 
 	/*
 	 * Wait till all kids have terminated.  Stash away their
-	 * pid's in an array.
+	 * pids in an array.
 	 */
 	kid_count = 0;
 	errno = 0;
@@ -207,16 +63,15 @@ static void do_child_1(void)
 			continue;
 
 		if (!WIFEXITED(status)) {
-			tst_resm(TFAIL, "Child %d did not exit "
+			tst_res(TFAIL, "Child %d did not exit "
 				 "normally", ret_val);
 			flag = FAILED;
-			printf("status: %d\n", status);
 		} else {
 			if (WEXITSTATUS(status) != 3) {
-				tst_resm(TFAIL, "Child %d"
+				tst_res(TFAIL, "Child %d "
 					 "exited with wrong "
 					 "status", ret_val);
-				tst_resm(TFAIL, "Expected 3 "
+				tst_res(TFAIL, "Expected 3 "
 					 "got %d ", WEXITSTATUS(status));
 				flag = FAILED;
 			}
@@ -239,16 +94,16 @@ static void do_child_1(void)
 		}
 
 		if (!found) {
-			tst_resm(TFAIL, "Did not find a "
+			tst_res(TFAIL, "Did not find a "
 				 "wait_kid_pid for the "
 				 "fork_kid_pid of %d", wait_kid_pid[i]);
 			for (k = 0; k < MAXKIDS; k++) {
-				tst_resm(TFAIL,
+				tst_res(TFAIL,
 					 "fork_kid_pid[%d] = "
 					 "%d", k, fork_kid_pid[k]);
 			}
 			for (k = 0; k < kid_count; k++) {
-				tst_resm(TFAIL,
+				tst_res(TFAIL,
 					 "wait_kid_pid[%d] = "
 					 "%d", k, wait_kid_pid[k]);
 			}
@@ -256,48 +111,15 @@ static void do_child_1(void)
 		}
 	}
 
-	if (flag)
-		exit(1);
-	else
-		exit(0);
-}
-
-#ifdef UCLINUX
-/*
- * do_child_2_uclinux()
- *	sets up sigint handler again, then calls the normal child 2 function
- */
-static void do_child_2_uclinux(void)
-{
-	setup_sigint();
-	do_exit();
-}
-#endif
-
-static void setup(void)
-{
-	TEST_PAUSE;
-}
-
-static void cleanup(void)
-{
-}
-
-static void inthandlr(void)
-{
-	intintr++;
-}
-
-static void wait_for_parent(void)
-{
-	int testvar;
+	memset(fork_kid_pid, 0, sizeof(*fork_kid_pid) * MAXKIDS);
 
-	while (!intintr)
-		testvar = 0;
+	exit(flag);
 }
 
-static void do_exit(void)
-{
-	wait_for_parent();
-	exit(3);
-}
+static struct tst_test test = {
+	.tid = "waitpid06",
+	.forks_child = 1,
+	.needs_checkpoints = 1,
+	.cleanup = cleanup,
+	.test_all = waitpid_test,
+};
diff --git a/testcases/kernel/syscalls/waitpid/waitpid_common.h b/testcases/kernel/syscalls/waitpid/waitpid_common.h
new file mode 100644
index 0000000..909468a
--- /dev/null
+++ b/testcases/kernel/syscalls/waitpid/waitpid_common.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016 Linux Test Project
+ *
+ * Licensed under the GNU GPLv2 or later.
+ * This program is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ */
+
+#ifndef WAITPID_COMMON_H__
+#define WAITPID_COMMON_H__
+
+#include <sys/types.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include "tst_test.h"
+
+#define	FAILED	1
+#define	MAXKIDS	8
+
+static pid_t *fork_kid_pid;
+
+static void do_child_1(void);
+
+static void cleanup(void)
+{
+	int i;
+
+	for (i = 0; i < MAXKIDS; i++) {
+		if (fork_kid_pid[i] > 0) {
+			kill(fork_kid_pid[i], SIGKILL);
+			waitpid(fork_kid_pid[i], NULL, 0);
+		}
+	}
+}
+
+static void waitpid_test(void)
+{
+	pid_t pid;
+	int status;
+
+	fork_kid_pid = SAFE_MMAP(NULL, sizeof(*fork_kid_pid) * MAXKIDS,
+				 PROT_READ | PROT_WRITE,
+				 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+
+	pid = SAFE_FORK();
+	if (pid == 0) {
+		do_child_1();
+	} else {
+		SAFE_WAITPID(pid, &status, 0);
+		if (WEXITSTATUS(status) != 0)
+			tst_res(TFAIL, "Child returned bad status");
+		else
+			tst_res(TPASS, "Child returned good status");
+	}
+}
+
+static void do_exit(int stop)
+{
+	TST_CHECKPOINT_WAIT(0);
+
+	if (stop)
+		kill(getpid(), SIGSTOP);
+
+	exit(3);
+}
+
+#endif /* WAITPID_COMMON_H__ */
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 3/8] waitpid07: use the new API
  2016-07-15 14:39 [LTP] waitpid: new API Stanislav Kholmanskikh
  2016-07-15 14:39 ` [LTP] [PATCH 1/8] tst_safe_macros: SAFE_GETPGID Stanislav Kholmanskikh
  2016-07-15 14:39 ` [LTP] [PATCH 2/8] waitpid06: use the new API Stanislav Kholmanskikh
@ 2016-07-15 14:39 ` Stanislav Kholmanskikh
  2016-07-15 14:39 ` [LTP] [PATCH 4/8] waitpid09: " Stanislav Kholmanskikh
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 24+ messages in thread
From: Stanislav Kholmanskikh @ 2016-07-15 14:39 UTC (permalink / raw)
  To: ltp

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
 testcases/kernel/syscalls/waitpid/waitpid07.c |  268 ++++---------------------
 1 files changed, 44 insertions(+), 224 deletions(-)

diff --git a/testcases/kernel/syscalls/waitpid/waitpid07.c b/testcases/kernel/syscalls/waitpid/waitpid07.c
index 92f921d..452621c 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid07.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid07.c
@@ -1,211 +1,64 @@
 /*
+ * Copyright (c) International Business Machines  Corp., 2001
  *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * This program is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
  *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * History
+ *	07/2001 John George
+ *		-Ported
+ *      04/2002 wjhuie sigset cleanups
  */
 
 /*
- * NAME
- *	waitpid07.c
- *
  * DESCRIPTION
- *	Tests to see if pid's returned from fork and waitpid are same.
+ *	Tests to see if pids returned from fork and waitpid are same.
  *
  * ALGORITHM
  *	Check proper functioning of waitpid with pid = -1 and arg = WNOHANG
- *
- * USAGE:  <for command-line>
- *      waitpid07 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- *      where,  -c n : Run n copies concurrently.
- *              -e   : Turn on errno logging.
- *              -i n : Execute test n times.
- *              -I x : Execute test for x seconds.
- *              -P x : Pause for x seconds between iterations.
- *              -t   : Turn on syscall timing.
- *
- * History
- *	07/2001 John George
- *		-Ported
- *      04/2002 wjhuie sigset cleanups
- *
- * Restrictions
- *	None
  */
 
-#include <sys/types.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include "test.h"
-
-static void setup_sigint(void);
-static void do_child_1(void);
-static void setup(void);
-static void cleanup(void);
-
-char *TCID = "waitpid07";
-int TST_TOTAL = 1;
-
-volatile int intintr;
-static int flag;
-static void inthandlr();
-static void do_exit(void);
-
-#define	FAILED	1
-#define MAXKIDS	8
-
-#ifdef UCLINUX
-static char *argv0;
-static void do_child_2_uclinux(void);
-#endif
-
-int main(int argc, char **argv)
-{
-	int lc;
-
-	int status;
-	int fail = 0;
-	int pid;
-
-	tst_parse_opts(argc, argv, NULL, NULL);
-
-#ifdef UCLINUX
-	argv0 = argv[0];
-
-	maybe_run_child(&do_child_1, "n", 1);
-	maybe_run_child(&do_child_2_uclinux, "n", 2);
-#endif
-
-	setup();
-
-	/* check for looping state if -i option is given */
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		pid = FORK_OR_VFORK();
-		if (pid < 0) {
-			tst_resm(TFAIL, "Fork Failed, may be OK under stress");
-		} else if (pid == 0) {
-
-			/*
-			 * Child:
-			 * Set up to catch SIGINT.  The kids will wait till a
-			 * SIGINT has been received before they proceed.
-			 */
-#ifdef UCLINUX
-			if (self_exec(argv[0], "n", 1) < 0) {
-				tst_resm(TINFO, "self_exec failed");
-				exit(pid);
-			}
-#else
-			do_child_1();
-#endif
-		} else {
-			fail = 0;
-			waitpid(pid, &status, 0);
-			if (WEXITSTATUS(status) != 0) {
-				tst_resm(TFAIL, "child returned bad status");
-				fail = 1;
-			}
-			if (fail)
-				tst_resm(TFAIL, "%s FAILED", TCID);
-			else
-				tst_resm(TPASS, "%s PASSED", TCID);
-		}
-	}
-
-	cleanup();
-	tst_exit();
-}
-
-/*
- * setup_sigint()
- *	Sets up a SIGINT handler
- */
-static void setup_sigint(void)
-{
-	if ((sig_t) signal(SIGINT, inthandlr) == SIG_ERR) {
-		tst_resm(TFAIL, "signal SIGINT failed. " "errno = %d", errno);
-		exit(-1);
-	}
-}
+#include "waitpid_common.h"
 
 static void do_child_1(void)
 {
-	int kid_count, fork_kid_pid[MAXKIDS];
-	int ret_val;
+	int kid_count;
+	pid_t ret_val;
 	int i, j, k, found;
-	int group1, group2;
-	int wait_kid_pid[MAXKIDS], status;
-
-	setup_sigint();
-
-	group1 = getpgrp();
+	pid_t wait_kid_pid[MAXKIDS];
+	int status;
+	int flag = 0;
 
 	for (kid_count = 0; kid_count < MAXKIDS; kid_count++) {
 		if (kid_count == (MAXKIDS / 2))
-			group2 = setpgrp();
-
-		intintr = 0;
-		ret_val = FORK_OR_VFORK();
-		if (ret_val == 0) {
-#ifdef UCLINUX
-			if (self_exec(argv0, "n", 2) < 0) {
-				tst_resm(TFAIL, "Fork kid %d failed. "
-					 "errno = %d", kid_count, errno);
-				exit(ret_val);
-			}
-#else
-			do_exit();
-#endif
-		}
+			SAFE_SETPGID(0, 0);
 
-		if (ret_val < 0) {
-			tst_brkm(TFAIL, NULL, "Fork kid %d failed. "
-				 "errno = %d", kid_count, errno);
-		}
+		ret_val = SAFE_FORK();
+		if (ret_val == 0)
+			do_exit(0);
 
-		/* parent */
 		fork_kid_pid[kid_count] = ret_val;
 	}
 
 	/* Check that waitpid with WNOHANG returns zero */
 	ret_val = waitpid(-1, &status, WNOHANG);
 	if (ret_val != 0) {
-		tst_resm(TFAIL, "Waitpid returned wrong value");
-		tst_resm(TFAIL, "Expected 0 got %d", ret_val);
+		tst_res(TFAIL, "Waitpid returned wrong value");
+		tst_res(TFAIL, "Expected 0 got %d", ret_val);
 		flag = FAILED;
 	}
-#ifdef UCLINUX
-	/* Give the kids a chance to setup SIGINT again, since this is
-	 * cleared by exec().
-	 */
-	sleep(3);
-#endif
 
-	/* Now send all the kids a SIGINT to tell them to
-	 * proceed
-	 */
-	for (i = 0; i < MAXKIDS; i++) {
-		if (kill(fork_kid_pid[i], SIGINT) < 0) {
-			tst_brkm(TFAIL, NULL, "Kill of child %d "
-				 "failed, errno = %d", i, errno);
-		}
-	}
+	TST_CHECKPOINT_WAKE2(0, MAXKIDS);
 
 	/*
 	 * Wait till all kids have terminated.  Stash away their
@@ -219,15 +72,15 @@ static void do_child_1(void)
 			continue;
 
 		if (!WIFEXITED(status)) {
-			tst_resm(TFAIL, "Child %d did not exit "
+			tst_res(TFAIL, "Child %d did not exit "
 				 "normally", ret_val);
 			flag = FAILED;
 		} else {
 			if (WEXITSTATUS(status) != 3) {
-				tst_resm(TFAIL, "Child %d "
+				tst_res(TFAIL, "Child %d "
 					 "exited with wrong "
 					 "status", ret_val);
-				tst_resm(TFAIL, "Expected 3 "
+				tst_res(TFAIL, "Expected 3 "
 					 "got %d ", WEXITSTATUS(status));
 				flag = FAILED;
 			}
@@ -250,16 +103,16 @@ static void do_child_1(void)
 		}
 
 		if (!found) {
-			tst_resm(TFAIL, "Did not find a "
+			tst_res(TFAIL, "Did not find a "
 				 "wait_kid_pid for the "
 				 "fork_kid_pid of %d", wait_kid_pid[i]);
 			for (k = 0; k < MAXKIDS; k++) {
-				tst_resm(TFAIL,
+				tst_res(TFAIL,
 					 "fork_kid_pid[%d] = "
 					 "%d", k, fork_kid_pid[k]);
 			}
 			for (k = 0; k < kid_count; k++) {
-				tst_resm(TFAIL,
+				tst_res(TFAIL,
 					 "wait_kid_pid[%d] = "
 					 "%d", k, wait_kid_pid[k]);
 			}
@@ -267,48 +120,15 @@ static void do_child_1(void)
 		}
 	}
 
-	if (flag)
-		exit(1);
-	else
-		exit(0);
-}
+	memset(fork_kid_pid, 0, sizeof(*fork_kid_pid) * MAXKIDS);
 
-#ifdef UCLINUX
-/*
- * do_child_2_uclinux()
- *	sets up sigint handler again, then calls the normal child 2 function
- */
-static void do_child_2_uclinux(void)
-{
-	setup_sigint();
-	do_exit();
-}
-#endif
-
-static void setup(void)
-{
-	TEST_PAUSE;
+	exit(flag);
 }
 
-static void cleanup(void)
-{
-}
-
-static void inthandlr(void)
-{
-	intintr++;
-}
-
-static void wait_for_parent(void)
-{
-	int testvar;
-
-	while (!intintr)
-		testvar = 0;
-}
-
-static void do_exit(void)
-{
-	wait_for_parent();
-	exit(3);
-}
+static struct tst_test test = {
+	.tid = "waitpid07",
+	.forks_child = 1,
+	.needs_checkpoints = 1,
+	.cleanup = cleanup,
+	.test_all = waitpid_test,
+};
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 4/8] waitpid09: use the new API
  2016-07-15 14:39 [LTP] waitpid: new API Stanislav Kholmanskikh
                   ` (2 preceding siblings ...)
  2016-07-15 14:39 ` [LTP] [PATCH 3/8] waitpid07: " Stanislav Kholmanskikh
@ 2016-07-15 14:39 ` Stanislav Kholmanskikh
  2016-07-18 14:18   ` Cyril Hrubis
  2016-07-15 14:39 ` [LTP] [PATCH 5/8] waitpid11: " Stanislav Kholmanskikh
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 24+ messages in thread
From: Stanislav Kholmanskikh @ 2016-07-15 14:39 UTC (permalink / raw)
  To: ltp

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
 testcases/kernel/syscalls/waitpid/waitpid09.c |  375 +++++++++----------------
 1 files changed, 140 insertions(+), 235 deletions(-)

diff --git a/testcases/kernel/syscalls/waitpid/waitpid09.c b/testcases/kernel/syscalls/waitpid/waitpid09.c
index 1339c82..fad3810 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid09.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid09.c
@@ -1,26 +1,26 @@
 /*
+ * Copyright (c) International Business Machines  Corp., 2001
  *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * This program is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
  *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * History
+ *	07/2001 John George
+ *		-Ported
+ *      04/2002 wjhuie sigset cleanups
  */
 
 /*
- * NAME
- *	waitpid09.c
- *
  * DESCRIPTION
  *	Check ability of parent to wait until child returns, and that the
  *	child's process id is returned through the waitpid. Check that
@@ -36,22 +36,6 @@
  *		Parent calls a waitpid with no children waiting. Waitpid
  *		should return a -1 since there are no children to wait for.
  *
- * USAGE:  <for command-line>
- *      waitpid09 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- *      where,  -c n : Run n copies concurrently.
- *              -e   : Turn on errno logging.
- *              -i n : Execute test n times.
- *              -I x : Execute test for x seconds.
- *              -P x : Pause for x seconds between iterations.
- *              -t   : Turn on syscall timing.
- *
- * History
- *	07/2001 John George
- *		-Ported
- *      04/2002 wjhuie sigset cleanups
- *
- * Restrictions
- *	None
  */
 
 #define _GNU_SOURCE 1
@@ -60,243 +44,164 @@
 #include <errno.h>
 #include <sys/wait.h>
 #include <stdlib.h>
+#include "tst_test.h"
 
-#include "test.h"
+static pid_t pid;
 
-char *TCID = "waitpid09";
-int TST_TOTAL = 1;
-volatile int intintr;
-
-static void setup(void);
-static void cleanup(void);
-static void inthandlr();
 static void do_exit(void);
-static void setup_sigint(void);
-#ifdef UCLINUX
-static void do_exit_uclinux(void);
-#endif
 
-int main(int argc, char **argv)
+static void cleanup(void)
 {
-	int lc;
-
-	int fail, pid, status, ret;
-
-	tst_parse_opts(argc, argv, NULL, NULL);
-
-#ifdef UCLINUX
-	maybe_run_child(&do_exit_uclinux, "");
-#endif
-
-	setup();
-
-	pid = FORK_OR_VFORK();
-	if (pid < 0) {
-		tst_brkm(TFAIL, cleanup, "Fork Failed");
-	} else if (pid == 0) {
-		/*
-		 * Child:
-		 * Set up to catch SIGINT.  The kids will wait till a
-		 * SIGINT has been received before they proceed.
-		 */
-		setup_sigint();
-
-		/* check for looping state if -i option is given */
-		for (lc = 0; TEST_LOOPING(lc); lc++) {
-			/* reset tst_count in case we are looping */
-			tst_count = 0;
-
-			intintr = 0;
-
-			fail = 0;
-			pid = FORK_OR_VFORK();
-			if (pid < 0) {
-				tst_brkm(TFAIL, cleanup, "Fork failed.");
-			} else if (pid == 0) {	/* child */
-#ifdef UCLINUX
-				if (self_exec(argv[0], "") < 0) {
-					tst_brkm(TFAIL, cleanup,
-						 "self_exec failed");
-				}
-#else
-				do_exit();
-#endif
-			} else {	/* parent */
-
-				/*
-				 *Check that waitpid with WNOHANG returns zero
-				 */
-				while (((ret = waitpid(pid, &status, WNOHANG))
-					!= 0) || (errno == EINTR)) {
-					if (ret == -1)
-						continue;
-
-					tst_resm(TFAIL, "return value for "
-						 "WNOHANG expected 0 got %d",
-						 ret);
-					fail = 1;
-				}
-#ifdef UCLINUX
-				/* Give the kids a chance to setup SIGINT again, since
-				 * this is cleared by exec().
-				 */
-				sleep(3);
-#endif
-
-				/* send SIGINT to child to tell it to proceed */
-				if (kill(pid, SIGINT) < 0) {
-					tst_resm(TFAIL, "Kill of child failed, "
-						 "errno = %d", errno);
-					fail = 1;
-				}
-
-				while (((ret = waitpid(pid, &status, 0)) != -1)
-				       || (errno == EINTR)) {
-					if (ret == -1)
-						continue;
-
-					if (ret != pid) {
-						tst_resm(TFAIL, "Expected %d "
-							 "got %d as proc id of "
-							 "child", pid, ret);
-						fail = 1;
-					}
-
-					if (status != 0) {
-						tst_resm(TFAIL, "status value "
-							 "got %d expected 0",
-							 status);
-						fail = 1;
-					}
-				}
-			}
+	if (pid > 0) {
+		kill(pid, SIGKILL);
+		waitpid(pid, NULL, 0);
+	}
+}
 
-			pid = FORK_OR_VFORK();
-			if (pid < 0) {
-				tst_brkm(TFAIL, cleanup, "Second fork failed.");
-			} else if (pid == 0) {	/* child */
-				exit(0);
-			} else {	/* parent */
-				/* Give the child time to startup and exit */
-				sleep(2);
+static void case0(void)
+{
+	pid_t ret;
+	int status;
+	int fail = 0;
+
+	pid = SAFE_FORK();
+	if (pid == 0)
+		do_exit();
+
+	/*
+	 *Check that waitpid with WNOHANG returns zero
+	 */
+	while (((ret = waitpid(pid, &status, WNOHANG))
+		!= 0) || (errno == EINTR)) {
+		if (ret == -1)
+			continue;
+
+		tst_res(TFAIL, "return value for "
+			 "WNOHANG expected 0 got %d",
+			 ret);
+		fail = 1;
+	}
 
-				while (((ret = waitpid(pid, &status, WNOHANG))
-					!= -1) || (errno == EINTR)) {
-					if (ret == -1)
-						continue;
+	TST_CHECKPOINT_WAKE(0);
 
-					if (ret != pid) {
-						tst_resm(TFAIL, "proc id %d "
-							 "and retval %d do not "
-							 "match", pid, ret);
-						fail = 1;
-					}
+	while (((ret = waitpid(pid, &status, 0)) != -1)
+	       || (errno == EINTR)) {
+		if (ret == -1)
+			continue;
 
-					if (status != 0) {
-						tst_resm(TFAIL, "non zero "
-							 "status received %d",
-							 status);
-						fail = 1;
-					}
-				}
-			}
+		if (ret != pid) {
+			tst_res(TFAIL, "Expected %d "
+				 "got %d as proc id of "
+				 "child", pid, ret);
+			fail = 1;
+		}
 
-			if (fail)
-				tst_resm(TFAIL, "case 1 FAILED");
-			else
-				tst_resm(TPASS, "case 1 PASSED");
+		if (status != 0) {
+			tst_res(TFAIL, "status value "
+				 "got %d expected 0",
+				 status);
+			fail = 1;
+		}
+	}
 
-			fail = 0;
-			ret = waitpid(pid, &status, 0);
+	pid = 0;
 
-			if (ret != -1) {
-				tst_resm(TFAIL, "Expected -1 got %d", ret);
-				fail = 1;
-			}
-			if (errno != ECHILD) {
-				tst_resm(TFAIL, "Expected ECHILD got %d",
-					 errno);
-				fail = 1;
-			}
+	pid = SAFE_FORK();
+	if (pid == 0)
+		exit(0);
 
-			ret = waitpid(pid, &status, WNOHANG);
-			if (ret != -1) {
-				tst_resm(TFAIL, "WNOHANG: Expected -1 got %d",
-					 ret);
-				fail = 1;
-			}
-			if (errno != ECHILD) {
-				tst_resm(TFAIL, "WNOHANG: Expected ECHILD got "
-					 "%d", errno);
-				fail = 1;
-			}
+	while (((ret = waitpid(pid, &status, WNOHANG))
+		!= -1) || (errno == EINTR)) {
+		if (ret == -1)
+			continue;
+		if (ret == 0)
+			continue;
 
-			if (fail)
-				tst_resm(TFAIL, "case 2 FAILED");
-			else
-				tst_resm(TPASS, "case 2 PASSED");
+		if (ret != pid) {
+			tst_res(TFAIL, "proc id %d "
+				 "and retval %d do not "
+				 "match", pid, ret);
+			fail = 1;
 		}
 
-		cleanup();
-	} else {
-		/* wait for the child to return */
-		waitpid(pid, &status, 0);
-		if (WEXITSTATUS(status) != 0) {
-			tst_brkm(TBROK, cleanup, "child returned bad "
-				 "status");
+		if (status != 0) {
+			tst_res(TFAIL, "non zero "
+				 "status received %d",
+				 status);
+			fail = 1;
 		}
 	}
 
-	tst_exit();
+	pid = 0;
+
+	if (fail)
+		tst_res(TFAIL, "case 0 FAILED");
+	else
+		tst_res(TPASS, "case 0 PASSED");
 }
 
-/*
- * setup_sigint()
- *	sets up a SIGINT handler
- */
-static void setup_sigint(void)
+static void case1(void)
 {
-	if ((sig_t) signal(SIGINT, inthandlr) == SIG_ERR) {
-		tst_brkm(TFAIL, cleanup, "signal SIGINT failed, errno = %d",
+	pid_t ret;
+	int status;
+	int fail = 0;
+
+	ret = waitpid(-1, &status, 0);
+
+	if (ret != -1) {
+		tst_res(TFAIL, "Expected -1 got %d", ret);
+		fail = 1;
+	}
+	if (errno != ECHILD) {
+		tst_res(TFAIL, "Expected ECHILD got %d",
 			 errno);
+		fail = 1;
 	}
-}
-
-static void setup(void)
-{
-	TEST_PAUSE;
-}
 
-static void cleanup(void)
-{
-}
+	ret = waitpid(-1, &status, WNOHANG);
+	if (ret != -1) {
+		tst_res(TFAIL, "WNOHANG: Expected -1 got %d",
+			 ret);
+		fail = 1;
+	}
+	if (errno != ECHILD) {
+		tst_res(TFAIL, "WNOHANG: Expected ECHILD got "
+			 "%d", errno);
+		fail = 1;
+	}
 
-static void inthandlr(void)
-{
-	intintr++;
+	if (fail)
+		tst_res(TFAIL, "case 1 FAILED");
+	else
+		tst_res(TPASS, "case 1 PASSED");
 }
 
-static void wait_for_parent(void)
+static void waitpid09_test(unsigned int id)
 {
-	int testvar;
-	while (!intintr)
-		testvar = 0;
+	switch (id) {
+	case 0:
+		case0();
+		break;
+	case 1:
+		case1();
+		break;
+	default:
+		tst_brk(TBROK, "Unknown %d", id);
+	}
 }
 
 static void do_exit(void)
 {
-	wait_for_parent();
+	TST_CHECKPOINT_WAIT(0);
+
 	exit(0);
 }
 
-#ifdef UCLINUX
-/*
- * do_exit_uclinux()
- *	Sets up SIGINT handler again, then calls do_exit
- */
-static void do_exit_uclinux(void)
-{
-	setup_sigint();
-	do_exit();
-}
-#endif
+static struct tst_test test = {
+	.tid = "waitpid09",
+	.forks_child = 1,
+	.needs_checkpoints = 1,
+	.cleanup = cleanup,
+	.test = waitpid09_test,
+	.tcnt = 2,
+};
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 5/8] waitpid11: use the new API
  2016-07-15 14:39 [LTP] waitpid: new API Stanislav Kholmanskikh
                   ` (3 preceding siblings ...)
  2016-07-15 14:39 ` [LTP] [PATCH 4/8] waitpid09: " Stanislav Kholmanskikh
@ 2016-07-15 14:39 ` Stanislav Kholmanskikh
  2016-07-18 15:01   ` Cyril Hrubis
  2016-07-15 14:39 ` [LTP] [PATCH 6/8] waitpid12: " Stanislav Kholmanskikh
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 24+ messages in thread
From: Stanislav Kholmanskikh @ 2016-07-15 14:39 UTC (permalink / raw)
  To: ltp

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
 testcases/kernel/syscalls/waitpid/waitpid11.c |  249 ++++++-------------------
 1 files changed, 56 insertions(+), 193 deletions(-)

diff --git a/testcases/kernel/syscalls/waitpid/waitpid11.c b/testcases/kernel/syscalls/waitpid/waitpid11.c
index 135ec56..0cc7bcb 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid11.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid11.c
@@ -1,157 +1,61 @@
 /*
+ * Copyright (c) International Business Machines  Corp., 2001
  *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * This program is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
  *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * History
+ *	07/2001 John George
+ *		-Ported
+ *      04/2002 wjhuie sigset cleanups
  */
 
 /*
- * NAME
- *	waitpid11.c
- *
  * DESCRIPTION
- *	Tests to see if pid's returned from fork and waitpid are same
+ *	Tests to see if pids returned from fork and waitpid are same
  *
  * ALGORITHM
  * 	Check proper functioning of waitpid with pid = -1 and arg = 0
- *
- * USAGE:  <for command-line>
- *      waitpid11 [-c n] [-t]
- *      where,  -c n : Run n copies concurrently.
- *              -t   : Turn on syscall timing.
- *
- * History
- *	07/2001 John George
- *		-Ported
- *      04/2002 wjhuie sigset cleanups
- *
- * Restrictions
- *	None
  */
 
-#include <sys/types.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include "test.h"
-
-#define	MAXKIDS	8
-
-char *TCID = "waitpid11";
-int TST_TOTAL = 1;
+#include "waitpid_common.h"
 
-volatile int intintr;
-static void setup(void);
-static void cleanup(void);
-static void inthandlr();
-static void wait_for_parent(void);
-static void do_exit(void);
-static void setup_sigint(void);
-#ifdef UCLINUX
-static void do_exit_uclinux(void);
-#endif
-
-static int fail;
-static int fork_kid_pid[MAXKIDS];
-
-int main(int ac, char **av)
+static void do_child_1(void)
 {
 	int kid_count, ret_val, status;
 	int i, j, k, found;
-	int group1, group2;
-	int wait_kid_pid[MAXKIDS];
-	int pid;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-#ifdef UCLINUX
-	maybe_run_child(&do_exit_uclinux, "");
-#endif
-
-	setup();
-
-	tst_count = 0;
-	fail = 0;
-
-	/*
-	 * Need to have test run from child as test driver causes
-	 * test to be a session leader and setpgrp fails.
-	 */
-
-	pid = FORK_OR_VFORK();
-	if (pid > 0) {
-		waitpid(pid, &status, 0);
-		if (WEXITSTATUS(status) != 0) {
-			tst_resm(TFAIL, "child returned bad status");
-			fail = 1;
-		}
-		if (fail)
-			tst_resm(TFAIL, "%s FAILED", TCID);
-		else
-			tst_resm(TPASS, "%s PASSED", TCID);
-		tst_exit();
-	} else if (pid < 0)
-		tst_brkm(TBROK, cleanup, "fork failed");
-
-	/*
-	 * Set up to catch SIGINT.  The kids will wait till a SIGINT
-	 * has been received before they proceed.
-	 */
-	setup_sigint();
+	pid_t group;
+	pid_t wait_kid_pid[MAXKIDS];
+	int fail = 0;
 
-	group1 = getpgrp();
+	group = SAFE_GETPGID(0);
 
 	for (kid_count = 0; kid_count < MAXKIDS; kid_count++) {
 		if (kid_count == (MAXKIDS / 2))
-			group2 = setpgrp();
-
-		intintr = 0;
-		ret_val = FORK_OR_VFORK();
-		if (ret_val == 0) {
-#ifdef UCLINUX
-			if (self_exec(av[0], "") < 0)
-				tst_resm(TFAIL | TERRNO, "self_exec kid %d "
-					 "failed", kid_count);
-#else
-			do_exit();
-#endif
-		}
+			SAFE_SETPGID(0, 0);
 
-		if (ret_val < 0)
-			tst_brkm(TBROK|TERRNO, cleanup, "Fork kid %d failed",
-				 kid_count);
+		ret_val = SAFE_FORK();
+		if (ret_val == 0)
+			do_exit(0);
 
-		/* parent */
 		fork_kid_pid[kid_count] = ret_val;
 	}
 
-#ifdef UCLINUX
-	/* Give the kids a chance to setup SIGINT again, since this is
-	 * cleared by exec().
-	 */
-	sleep(3);
-#endif
-
-	/* Now send all the kids a SIGINT to tell them to proceed */
-	for (i = 0; i < MAXKIDS; i++)
-		if (kill(fork_kid_pid[i], SIGINT) < 0)
-			tst_resm(TFAIL | TERRNO, "Kill of child %d failed", i);
+	TST_CHECKPOINT_WAKE2(0, MAXKIDS);
 
 	/*
 	 * Wait till all kids have terminated.  Stash away their
-	 * pid's in an array.
+	 * pids in an array.
 	 */
 	kid_count = 0;
 	errno = 0;
@@ -160,14 +64,14 @@ int main(int ac, char **av)
 			continue;
 
 		if (!WIFEXITED(status)) {
-			tst_resm(TFAIL, "Child %d did not exit "
+			tst_res(TFAIL, "Child %d did not exit "
 				 "normally", ret_val);
 			fail = 1;
 		} else {
 			if (WEXITSTATUS(status) != 3) {
-				tst_resm(TFAIL, "Child %d exited with "
+				tst_res(TFAIL, "Child %d exited with "
 					 "wrong status", ret_val);
-				tst_resm(TFAIL, "Expected 3 got %d",
+				tst_res(TFAIL, "Expected 3 got %d",
 					 WEXITSTATUS(status));
 				fail = 1;
 			}
@@ -189,14 +93,14 @@ int main(int ac, char **av)
 			}
 		}
 		if (!found) {
-			tst_resm(TFAIL, "Did not find a fork_kid_pid "
+			tst_res(TFAIL, "Did not find a fork_kid_pid "
 				 "for the wait_kid_pid of %d", wait_kid_pid[i]);
 			for (k = 0; k < MAXKIDS; k++) {
-				tst_resm(TFAIL, "fork_kid_pid[%d] = "
+				tst_res(TFAIL, "fork_kid_pid[%d] = "
 					 "%d", k, fork_kid_pid[k]);
 			}
 			for (k = 0; k < kid_count; k++) {
-				tst_resm(TFAIL, "wait_kid_pid[%d] = "
+				tst_res(TFAIL, "wait_kid_pid[%d] = "
 					 "%d", k, wait_kid_pid[k]);
 			}
 			fail = 1;
@@ -204,9 +108,9 @@ int main(int ac, char **av)
 	}
 
 	if (kid_count != (MAXKIDS / 2)) {
-		tst_resm(TFAIL, "Wrong number of children waited on "
+		tst_res(TFAIL, "Wrong number of children waited on "
 			 "for pid = 0");
-		tst_resm(TFAIL, "Expected 4 got %d", kid_count);
+		tst_res(TFAIL, "Expected 4 got %d", kid_count);
 		fail = 1;
 	}
 
@@ -214,19 +118,19 @@ int main(int ac, char **av)
 
 	kid_count = 0;
 	errno = 0;
-	while (((ret_val = waitpid(-(group1), &status, 0)) != -1) ||
+	while (((ret_val = waitpid(-(group), &status, 0)) != -1) ||
 	       (errno == EINTR)) {
 		if (ret_val == -1)
 			continue;
 		if (!WIFEXITED(status)) {
-			tst_resm(TFAIL, "Child %d did not exit "
+			tst_res(TFAIL, "Child %d did not exit "
 				 "normally", ret_val);
 			fail = 1;
 		} else {
 			if (WEXITSTATUS(status) != 3) {
-				tst_resm(TFAIL, "Child %d exited with "
+				tst_res(TFAIL, "Child %d exited with "
 					 "wrong status", ret_val);
-				tst_resm(TFAIL, "Expected 3 got %d",
+				tst_res(TFAIL, "Expected 3 got %d",
 					 WEXITSTATUS(status));
 				fail = 1;
 			}
@@ -248,80 +152,39 @@ int main(int ac, char **av)
 			}
 		}
 		if (!found) {
-			tst_resm(TFAIL, "Did not find a fork_kid_pid "
+			tst_res(TFAIL, "Did not find a fork_kid_pid "
 				 "for the wait_kid_pid of %d", wait_kid_pid[i]);
 			for (k = 0; k < MAXKIDS; k++)
-				tst_resm(TFAIL, "fork_kid_pid[%d] = "
+				tst_res(TFAIL, "fork_kid_pid[%d] = "
 					 "%d", k, fork_kid_pid[k]);
 			for (k = 0; k < kid_count; k++)
-				tst_resm(TFAIL, "wait_kid_pid[%d] = "
+				tst_res(TFAIL, "wait_kid_pid[%d] = "
 					 "%d", k, wait_kid_pid[k]);
 			fail = 1;
 		}
 	}
 
-	memset(fork_kid_pid, 0, sizeof(fork_kid_pid));
-
 	if (kid_count != (MAXKIDS / 2)) {
-		tst_resm(TFAIL, "Wrong number of children waited on "
+		tst_res(TFAIL, "Wrong number of children waited on "
 			 "for pid = 0");
-		tst_resm(TFAIL, "Expected 4 got %d", kid_count);
+		tst_res(TFAIL, "Expected 4 got %d", kid_count);
 		fail = 1;
 	}
 
 	if (fail)
-		tst_resm(TFAIL, "Test FAILED");
+		tst_res(TFAIL, "Test FAILED");
 	else
-		tst_resm(TPASS, "Test PASSED");
-
-	cleanup();
-	tst_exit();
-}
-
-static void setup_sigint(void)
-{
-	if (signal(SIGINT, inthandlr) == SIG_ERR)
-		tst_brkm(TFAIL | TERRNO, NULL, "signal SIGINT failed");
-}
-
-static void setup(void)
-{
-	TEST_PAUSE;
-}
+		tst_res(TPASS, "Test PASSED");
 
-static void cleanup(void)
-{
-	int i;
-
-	for (i = 0; i < MAXKIDS; i++) {
-		if (fork_kid_pid[i] > 0)
-			kill(fork_kid_pid[i], SIGKILL);
-	}
-}
-
-static void inthandlr(void)
-{
-	intintr++;
-}
+	memset(fork_kid_pid, 0, sizeof(*fork_kid_pid) * MAXKIDS);
 
-static void wait_for_parent(void)
-{
-	int testvar;
-
-	while (!intintr)
-		testvar = 0;
+	exit(fail);
 }
 
-static void do_exit(void)
-{
-	wait_for_parent();
-	exit(3);
-}
-
-#ifdef UCLINUX
-static void do_exit_uclinux(void)
-{
-	setup_sigint();
-	do_exit();
-}
-#endif
+static struct tst_test test = {
+	.tid = "waitpid11",
+	.forks_child = 1,
+	.needs_checkpoints = 1,
+	.cleanup = cleanup,
+	.test_all = waitpid_test,
+};
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 6/8] waitpid12: use the new API
  2016-07-15 14:39 [LTP] waitpid: new API Stanislav Kholmanskikh
                   ` (4 preceding siblings ...)
  2016-07-15 14:39 ` [LTP] [PATCH 5/8] waitpid11: " Stanislav Kholmanskikh
@ 2016-07-15 14:39 ` Stanislav Kholmanskikh
  2016-07-18 15:07   ` Cyril Hrubis
  2016-07-15 14:39 ` [LTP] [PATCH 7/8] waitpid13: " Stanislav Kholmanskikh
  2016-07-15 14:39 ` [LTP] [PATCH 8/8] waitpid08: " Stanislav Kholmanskikh
  7 siblings, 1 reply; 24+ messages in thread
From: Stanislav Kholmanskikh @ 2016-07-15 14:39 UTC (permalink / raw)
  To: ltp

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
 testcases/kernel/syscalls/waitpid/waitpid12.c |  250 ++++++-------------------
 1 files changed, 60 insertions(+), 190 deletions(-)

diff --git a/testcases/kernel/syscalls/waitpid/waitpid12.c b/testcases/kernel/syscalls/waitpid/waitpid12.c
index bf64662..a5b1fe9 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid12.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid12.c
@@ -1,184 +1,88 @@
 /*
+ * Copyright (c) International Business Machines  Corp., 2001
  *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * This program is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
  *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * NAME
- *	waitpid12.c
- *
- * DESCRIPTION
- *	Tests to see if pid's returned from fork and waitpid are same
- *
- * ALGORITHM
- *	Check proper functioning of waitpid with pid = -1 and arg = WNOHANG
- *
- * USAGE:  <for command-line>
- *      waitpid12 [-c n] [-t]
- *      where,  -c n : Run n copies concurrently.
- *              -t   : Turn on syscall timing.
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
  *
  * History
  *	07/2001 John George
  *		-Ported
  *      04/2002 wjhuie sigset testx for SIG_ERR not < 0, TPASS|TFAIL issued
  *      04/2002 wjhuie sigset cleanups
- *
- * Restrictions
- *	None
  */
 
-#include <sys/types.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include "test.h"
-
-#define	MAXKIDS	8
-
-char *TCID = "waitpid12";
-int TST_TOTAL = 1;
+/*
 
-volatile int intintr;
-static void setup(void);
-static void cleanup(void);
-static void inthandlr();
-static void wait_for_parent(void);
-static void do_exit(void);
-static void setup_sigint(void);
-#ifdef UCLINUX
-static void do_exit_uclinux(void);
-#endif
+ * DESCRIPTION
+ *	Tests to see if pids returned from fork and waitpid are same
+ *
+ * ALGORITHM
+ *	Check proper functioning of waitpid with pid = -1 and arg = WNOHANG
+ */
 
-static int fail;
+#include "waitpid_common.h"
 
-int main(int argc, char **argv)
+static void do_child_1(void)
 {
 	int kid_count, ret_val, status;
 	int i, j, k, found;
-	int group1, group2;
-	int fork_kid_pid[MAXKIDS], wait_kid_pid[MAXKIDS];
-	int pid;
-
-	tst_parse_opts(argc, argv, NULL, NULL);
-
-#ifdef UCLINUX
-	maybe_run_child(&do_exit_uclinux, "");
-#endif
-
-	setup();
+	pid_t group;
+	pid_t wait_kid_pid[MAXKIDS];
+	int fail = 0;
 
-	tst_count = 0;
-	fail = 0;
-
-	/*
-	 * Need to have test run from child as test driver causes
-	 * test to be a session leader and setpgrp fails.
-	 */
-
-	pid = FORK_OR_VFORK();
-	if (pid > 0) {
-		waitpid(pid, &status, 0);
-		if (WEXITSTATUS(status) != 0) {
-			tst_resm(TFAIL, "child returned bad status");
-			fail = 1;
-		}
-		if (fail)
-			tst_resm(TFAIL, "%s FAILED", TCID);
-		else
-			tst_resm(TPASS, "%s PASSED", TCID);
-		cleanup();
-		tst_exit();
-	} else if (pid < 0) {
-		tst_brkm(TBROK, cleanup, "fork failed");
-	}
-
-	/*
-	 * Set up to catch SIGINT.  The kids will wait till a SIGINT
-	 * has been received before they proceed.
-	 */
-	setup_sigint();
-
-	group1 = getpgrp();
+	group = SAFE_GETPGID(0);
 
 	for (kid_count = 0; kid_count < MAXKIDS; kid_count++) {
 		if (kid_count == (MAXKIDS / 2))
-			group2 = setpgrp();
+			SAFE_SETPGID(0, 0);
 
-		intintr = 0;
-		ret_val = FORK_OR_VFORK();
-		if (ret_val == 0) {
-#ifdef UCLINUX
-			if (self_exec(argv[0], "") < 0)
-				tst_resm(TFAIL, "self_exec kid %d "
-					 "failed", kid_count);
-#else
-			do_exit();
-#endif
-		}
-
-		if (ret_val < 0)
-			tst_resm(TFAIL | TERRNO, "forking kid %d failed",
-				 kid_count);
+		ret_val = SAFE_FORK();
+		if (ret_val == 0)
+			do_exit(0);
 
-		/* parent */
 		fork_kid_pid[kid_count] = ret_val;
 	}
 
 	/* Check that waitpid with WNOHANG returns zero */
 	ret_val = waitpid(0, &status, WNOHANG);
 	if (ret_val != 0) {
-		tst_resm(TFAIL, "Waitpid returned wrong value");
-		tst_resm(TFAIL, "Expected 0 got %d", ret_val);
+		tst_res(TFAIL, "Waitpid returned wrong value");
+		tst_res(TFAIL, "Expected 0 got %d", ret_val);
 		fail = 1;
 	}
-#ifdef UCLINUX
-	/* Give the kids a chance to setup SIGINT again, since this is
-	 * cleared by exec().
-	 */
-	sleep(3);
-#endif
 
-	/* Now send all the kids a SIGINT to tell them to proceed */
-	for (i = 0; i < MAXKIDS; i++)
-		if (kill(fork_kid_pid[i], SIGINT) < 0)
-			tst_resm(TFAIL | TERRNO, "killing child %d failed", i);
+	TST_CHECKPOINT_WAKE2(0, MAXKIDS);
 
 	/*
 	 * Wait till all kids have terminated.  Stash away their
-	 * pid's in an array.
+	 * pids in an array.
 	 */
 	kid_count = 0;
 	errno = 0;
-	sleep(2);
 	while (((ret_val = waitpid(0, &status, WNOHANG)) != -1) ||
 	       (errno == EINTR)) {
 		if ((ret_val == -1) || (ret_val == 0))
 			continue;
 
 		if (!WIFEXITED(status)) {
-			tst_resm(TFAIL, "Child %d did not exit "
+			tst_res(TFAIL, "Child %d did not exit "
 				 "normally", ret_val);
 			fail = 1;
 		} else {
 			if (WEXITSTATUS(status) != 3) {
-				tst_resm(TFAIL, "Child %d exited with "
+				tst_res(TFAIL, "Child %d exited with "
 					 "wrong status", ret_val);
-				tst_resm(TFAIL, "Expected 3 got %d",
+				tst_res(TFAIL, "Expected 3 got %d",
 					 WEXITSTATUS(status));
 				fail = 1;
 			}
@@ -200,22 +104,22 @@ int main(int argc, char **argv)
 			}
 		}
 		if (!found) {
-			tst_resm(TFAIL, "Did not find a wait_kid_pid "
+			tst_res(TFAIL, "Did not find a wait_kid_pid "
 				 "for the fork_kid_pid of %d", wait_kid_pid[i]);
 			for (k = 0; k < MAXKIDS; k++)
-				tst_resm(TFAIL, "fork_kid_pid[%d] = "
+				tst_res(TFAIL, "fork_kid_pid[%d] = "
 					 "%d", k, fork_kid_pid[k]);
 			for (k = 0; k < kid_count; k++)
-				tst_resm(TFAIL, "wait_kid_pid[%d] = "
+				tst_res(TFAIL, "wait_kid_pid[%d] = "
 					 "%d", k, wait_kid_pid[k]);
 			fail = 1;
 		}
 	}
 
 	if (kid_count != (MAXKIDS / 2)) {
-		tst_resm(TFAIL, "Wrong number of children waited on "
+		tst_res(TFAIL, "Wrong number of children waited on "
 			 "for pid = 0");
-		tst_resm(TFAIL, "Expected 4 got %d", kid_count);
+		tst_res(TFAIL, "Expected 4 got %d", kid_count);
 		fail = 1;
 	}
 
@@ -223,20 +127,20 @@ int main(int argc, char **argv)
 
 	kid_count = 0;
 	errno = 0;
-	while (((ret_val = waitpid(-(group1), &status, WNOHANG)) !=
+	while (((ret_val = waitpid(-(group), &status, WNOHANG)) !=
 		-1) || (errno == EINTR)) {
 		if (ret_val == -1 || ret_val == 0)
 			continue;
 
 		if (!WIFEXITED(status)) {
-			tst_resm(TFAIL, "Child %d did not exit "
+			tst_res(TFAIL, "Child %d did not exit "
 				 "normally", ret_val);
 			fail = 1;
 		} else {
 			if (WEXITSTATUS(status) != 3) {
-				tst_resm(TFAIL, "Child %d exited with "
+				tst_res(TFAIL, "Child %d exited with "
 					 "wrong status", ret_val);
-				tst_resm(TFAIL, "Expected 3 got %d",
+				tst_res(TFAIL, "Expected 3 got %d",
 					 WEXITSTATUS(status));
 				fail = 1;
 			}
@@ -258,72 +162,38 @@ int main(int argc, char **argv)
 			}
 		}
 		if (!found) {
-			tst_resm(TFAIL, "Did not find a wait_kid_pid "
+			tst_res(TFAIL, "Did not find a wait_kid_pid "
 				 "for the fork_kid_pid of %d", fork_kid_pid[j]);
 			for (k = 0; k < MAXKIDS; k++)
-				tst_resm(TFAIL, "fork_kid_pid[%d] = "
+				tst_res(TFAIL, "fork_kid_pid[%d] = "
 					 "%d", k, fork_kid_pid[k]);
 			for (k = 0; k < kid_count; k++)
-				tst_resm(TFAIL, "wait_kid_pid[%d] = "
+				tst_res(TFAIL, "wait_kid_pid[%d] = "
 					 "%d", k, wait_kid_pid[k]);
 			fail = 1;
 		}
 	}
 	if (kid_count != (MAXKIDS / 2)) {
-		tst_resm(TFAIL, "Wrong number of children waited on "
+		tst_res(TFAIL, "Wrong number of children waited on "
 			 "for pid = 0");
-		tst_resm(TFAIL, "Expected 4 got %d", kid_count);
+		tst_res(TFAIL, "Expected 4 got %d", kid_count);
 		fail = 1;
 	}
 
 	if (fail)
-		tst_resm(TFAIL, "Test FAILED");
+		tst_res(TFAIL, "Test FAILED");
 	else
-		tst_resm(TPASS, "Test PASSED");
-
-	tst_exit();
-}
-
-static void setup_sigint(void)
-{
-	if (signal(SIGINT, inthandlr) == SIG_ERR)
-		tst_brkm(TFAIL | TERRNO, NULL, "signal SIGINT failed");
-}
-
-static void setup(void)
-{
-	tst_sig(FORK, DEF_HANDLER, cleanup);
+		tst_res(TPASS, "Test PASSED");
 
-	TEST_PAUSE;
-}
-
-static void cleanup(void)
-{
-}
-
-static void inthandlr(void)
-{
-	intintr++;
-}
+	memset(fork_kid_pid, 0, sizeof(*fork_kid_pid) * MAXKIDS);
 
-static void wait_for_parent(void)
-{
-	int testvar;
-
-	while (!intintr)
-		testvar = 0;
+	exit(fail);
 }
 
-static void do_exit(void)
-{
-	wait_for_parent();
-	exit(3);
-}
-
-#ifdef UCLINUX
-static void do_exit_uclinux(void)
-{
-	setup_sigint();
-	do_exit();
-}
-#endif
+static struct tst_test test = {
+	.tid = "waitpid12",
+	.forks_child = 1,
+	.needs_checkpoints = 1,
+	.cleanup = cleanup,
+	.test_all = waitpid_test,
+};
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 7/8] waitpid13: use the new API
  2016-07-15 14:39 [LTP] waitpid: new API Stanislav Kholmanskikh
                   ` (5 preceding siblings ...)
  2016-07-15 14:39 ` [LTP] [PATCH 6/8] waitpid12: " Stanislav Kholmanskikh
@ 2016-07-15 14:39 ` Stanislav Kholmanskikh
  2016-07-15 14:39 ` [LTP] [PATCH 8/8] waitpid08: " Stanislav Kholmanskikh
  7 siblings, 0 replies; 24+ messages in thread
From: Stanislav Kholmanskikh @ 2016-07-15 14:39 UTC (permalink / raw)
  To: ltp

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
 testcases/kernel/syscalls/waitpid/waitpid13.c |  262 ++++++------------------
 1 files changed, 66 insertions(+), 196 deletions(-)

diff --git a/testcases/kernel/syscalls/waitpid/waitpid13.c b/testcases/kernel/syscalls/waitpid/waitpid13.c
index 5f03592..38e1182 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid13.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid13.c
@@ -1,172 +1,75 @@
 /*
+ * Copyright (c) International Business Machines  Corp., 2001
  *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * This program is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
  *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * History
+ *	07/2001 John George
+ *		-Ported
+ *      04/2002 wjhuie sigset cleanups
  */
 
 /*
- * NAME
- *	waitpid13.c
- *
  * DESCRIPTION
- *	Tests to see if pid's returned from fork and waitpid are same
+ *	Tests to see if pids returned from fork and waitpid are same
  *
  * ALGORITHM
  *	Check proper functioning of waitpid with pid = 0 and < -1 with arg
  *	WUNTRACED
- *
- * USAGE:  <for command-line>
- *      waitpid13 [-c n] [-t]
- *      where,  -c n : Run n copies concurrently.
- *              -t   : Turn on syscall timing.
- *
- * History
- *	07/2001 John George
- *		-Ported
- *      04/2002 wjhuie sigset cleanups
- *
- * Restrictions
- *	None
  */
 
-#include <sys/types.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include "test.h"
-
-#define	MAXKIDS	8
-
-char *TCID = "waitpid13";
-int TST_TOTAL = 1;
-
-volatile int intintr;
-static void setup(void);
-static void cleanup(void);
-static void inthandlr();
-static void wait_for_parent(void);
-static void do_exit(void);
-static void setup_sigint(void);
-#ifdef UCLINUX
-static void do_exit_uclinux(void);
-#endif
+#include "waitpid_common.h"
 
-static int fail;
-
-int main(int ac, char **av)
+static void do_child_1(void)
 {
 	int kid_count, ret_val, status;
 	int i, j, k, found;
-	int group1, group2;
-	int fork_kid_pid[MAXKIDS], wait_kid_pid[MAXKIDS];
-	int pid;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-#ifdef UCLINUX
-	maybe_run_child(&do_exit_uclinux, "");
-#endif
-
-	setup();
-
-	tst_count = 0;
-	fail = 0;
-
-	/*
-	 * Need to have test run from child as test driver causes
-	 * test to be a session leader and setpgrp fails.
-	 */
-	pid = FORK_OR_VFORK();
-	if (pid > 0) {
-		waitpid(pid, &status, 0);
-		if (WEXITSTATUS(status) != 0) {
-			tst_resm(TFAIL, "child returned bad status");
-			fail = 1;
-		}
-		if (fail)
-			tst_resm(TFAIL, "%s FAILED", TCID);
-		else
-			tst_resm(TPASS, "%s PASSED", TCID);
-
-		cleanup();
-		tst_exit();
-	} else if (pid < 0) {
-		tst_brkm(TBROK, cleanup, "fork failed");
-	}
-
-	/*
-	 * Set up to catch SIGINT.  The kids will wait till a SIGINT
-	 * has been received before they proceed.
-	 */
-	setup_sigint();
+	pid_t group;
+	pid_t wait_kid_pid[MAXKIDS];
+	int fail = 0;
 
-	group1 = getpgrp();
+	group = SAFE_GETPGID(0);
 
 	for (kid_count = 0; kid_count < MAXKIDS; kid_count++) {
 		if (kid_count == (MAXKIDS / 2))
-			group2 = setpgrp();
-
-		intintr = 0;
-		ret_val = FORK_OR_VFORK();
-		if (ret_val == 0) {
-#ifdef UCLINUX
-			if (self_exec(av[0], "") < 0) {
-				tst_resm(TFAIL | TERRNO, "self_exec kid %d "
-					 "failed", kid_count);
+			SAFE_SETPGID(0, 0);
 
-			}
-#else
-			do_exit();
-#endif
-		}
 
-		if (ret_val < 0)
-			tst_resm(TFAIL | TERRNO, "forking kid %d failed",
-				 kid_count);
+		ret_val = SAFE_FORK();
+		if (ret_val == 0)
+			do_exit(1);
 
-		/* parent */
 		fork_kid_pid[kid_count] = ret_val;
 	}
 
 	/* Check that waitpid with WNOHANG|WUNTRACED returns zero */
 	ret_val = waitpid(0, &status, WNOHANG | WUNTRACED);
 	if (ret_val != 0) {
-		tst_resm(TFAIL, "Waitpid returned wrong value"
+		tst_res(TFAIL, "Waitpid returned wrong value"
 			 "from waitpid(WNOHANG|WUNTRACED)");
-		tst_resm(TFAIL, "Expected 0 got %d", ret_val);
+		tst_res(TFAIL, "Expected 0 got %d", ret_val);
 		fail = 1;
 	}
-#ifdef UCLINUX
-	/* Give the kids a chance to setup SIGINT again, since this is
-	 * cleared by exec().
-	 */
-	sleep(3);
-#endif
 
-	/* Now send all the kids a SIGINT to tell them to proceed */
-	for (i = 0; i < MAXKIDS; i++) {
-		if (kill(fork_kid_pid[i], SIGINT) < 0) {
-			tst_resm(TFAIL | TERRNO, "killing child %d failed", i);
-			fail = 1;
-		}
-	}
+	TST_CHECKPOINT_WAKE2(0, MAXKIDS);
+
+	for (kid_count = 0; kid_count < MAXKIDS; kid_count++)
+		TST_PROCESS_STATE_WAIT(fork_kid_pid[kid_count], 'T');
 
 	/*
 	 * Wait till all kids have terminated.  Stash away their
-	 * pid's in an array.
+	 * pids in an array.
 	 */
 	kid_count = 0;
 	errno = 0;
@@ -177,22 +80,22 @@ int main(int ac, char **av)
 
 		if (!WIFEXITED(status)) {
 			if (!WIFSTOPPED(status)) {
-				tst_resm(TFAIL, "Child %d is not "
+				tst_res(TFAIL, "Child %d is not "
 					 "stopped", ret_val);
 				fail = 1;
 			} else {
 				if (WSTOPSIG(status) != SIGSTOP) {
-					tst_resm(TFAIL, "Child %d "
+					tst_res(TFAIL, "Child %d "
 						 "exited with wrong "
 						 "status", ret_val);
-					tst_resm(TFAIL, "Expected "
+					tst_res(TFAIL, "Expected "
 						 "SIGSTOP got %d",
 						 WEXITSTATUS(status));
 					fail = 1;
 				}
 			}
 			if (kill(ret_val, SIGCONT) < 0) {
-				tst_resm(TFAIL | TERRNO,
+				tst_res(TFAIL | TERRNO,
 					 "killing child %d failed", ret_val);
 				fail = 1;
 			}
@@ -222,22 +125,22 @@ int main(int ac, char **av)
 			}
 		}
 		if (!found) {
-			tst_resm(TFAIL, "Did not find a wait_kid_pid "
+			tst_res(TFAIL, "Did not find a wait_kid_pid "
 				 "for the fork_kid_pid of %d", wait_kid_pid[i]);
 			for (k = 0; k < MAXKIDS; k++)
-				tst_resm(TFAIL, "fork_kid_pid[%d] = "
+				tst_res(TFAIL, "fork_kid_pid[%d] = "
 					 "%d", k, fork_kid_pid[k]);
 			for (k = 0; k < kid_count; k++)
-				tst_resm(TFAIL, "wait_kid_pid[%d] = "
+				tst_res(TFAIL, "wait_kid_pid[%d] = "
 					 "%d", k, wait_kid_pid[k]);
 			fail = 1;
 		}
 	}
 
 	if (kid_count != (MAXKIDS / 2)) {
-		tst_resm(TFAIL, "Wrong number of children waited on "
+		tst_res(TFAIL, "Wrong number of children waited on "
 			 "for pid = 0");
-		tst_resm(TFAIL, "Expected %d got %d", MAXKIDS, kid_count);
+		tst_res(TFAIL, "Expected %d got %d", MAXKIDS, kid_count);
 		fail = 1;
 	}
 
@@ -245,28 +148,28 @@ int main(int ac, char **av)
 
 	kid_count = 0;
 	errno = 0;
-	while (((ret_val = waitpid(-(group1), &status, WUNTRACED)) !=
+	while (((ret_val = waitpid(-(group), &status, WUNTRACED)) !=
 		-1) || (errno == EINTR)) {
 		if (ret_val == -1)
 			continue;
 		if (!WIFEXITED(status)) {
 			if (!WIFSTOPPED(status)) {
-				tst_resm(TFAIL, "Child %d is not "
+				tst_res(TFAIL, "Child %d is not "
 					 "stopped", ret_val);
 				fail = 1;
 			} else {
 				if (WSTOPSIG(status) != SIGSTOP) {
-					tst_resm(TFAIL, "Child %d "
+					tst_res(TFAIL, "Child %d "
 						 "exited with wrong "
 						 "status", ret_val);
-					tst_resm(TFAIL, "Expected "
+					tst_res(TFAIL, "Expected "
 						 "SIGSTOP got %d",
 						 WEXITSTATUS(status));
 					fail = 1;
 				}
 			}
 			if (kill(ret_val, SIGCONT) < 0) {
-				tst_resm(TFAIL | TERRNO,
+				tst_res(TFAIL | TERRNO,
 					 "Killing child %d failed", ret_val);
 				fail = 1;
 			}
@@ -296,21 +199,21 @@ int main(int ac, char **av)
 			}
 		}
 		if (!found) {
-			tst_resm(TFAIL, "Did not find a wait_kid_pid "
+			tst_res(TFAIL, "Did not find a wait_kid_pid "
 				 "for the fork_kid_pid of %d", fork_kid_pid[j]);
 			for (k = 0; k < MAXKIDS; k++)
-				tst_resm(TFAIL, "fork_kid_pid[%d] = "
+				tst_res(TFAIL, "fork_kid_pid[%d] = "
 					 "%d", k, fork_kid_pid[k]);
 			for (k = 0; k < kid_count; k++)
-				tst_resm(TFAIL, "wait_kid_pid[%d] = "
+				tst_res(TFAIL, "wait_kid_pid[%d] = "
 					 "%d", k, wait_kid_pid[k]);
 			fail = 1;
 		}
 	}
 	if (kid_count != (MAXKIDS / 2)) {
-		tst_resm(TFAIL, "Wrong number of children waited on "
+		tst_res(TFAIL, "Wrong number of children waited on "
 			 "for pid = 0");
-		tst_resm(TFAIL, "Expected %d got %d", MAXKIDS, kid_count);
+		tst_res(TFAIL, "Expected %d got %d", MAXKIDS, kid_count);
 		fail = 1;
 	}
 
@@ -320,63 +223,30 @@ int main(int ac, char **av)
 	 */
 	ret_val = waitpid(-1, &status, WUNTRACED);
 	if (ret_val != -1) {
-		tst_resm(TFAIL, "Waitpid returned wrong value.");
-		tst_resm(TFAIL, "Expected -1 got %d", ret_val);
+		tst_res(TFAIL, "Waitpid returned wrong value.");
+		tst_res(TFAIL, "Expected -1 got %d", ret_val);
 		fail = 1;
 	}
 
 	if (errno != ECHILD) {
-		tst_resm(TFAIL, "Expected ECHILD from waitpid(WUNTRACED)");
+		tst_res(TFAIL, "Expected ECHILD from waitpid(WUNTRACED)");
 		fail = 1;
 	}
 
 	if (fail)
-		tst_resm(TFAIL, "Test FAILED");
+		tst_res(TFAIL, "Test FAILED");
 	else
-		tst_resm(TPASS, "Test PASSED");
+		tst_res(TPASS, "Test PASSED");
 
-	tst_exit();
-}
+	memset(fork_kid_pid, 0, sizeof(*fork_kid_pid) * MAXKIDS);
 
-static void setup_sigint(void)
-{
-	if (signal(SIGINT, inthandlr) == SIG_ERR)
-		tst_brkm(TFAIL | TERRNO, NULL, "signal SIGINT failed");
+	exit(fail);
 }
 
-static void setup(void)
-{
-	TEST_PAUSE;
-}
-
-static void cleanup(void)
-{
-}
-
-static void inthandlr(void)
-{
-	intintr++;
-}
-
-static void wait_for_parent(void)
-{
-	int testvar;
-
-	while (!intintr)
-		testvar = 0;
-}
-
-static void do_exit(void)
-{
-	wait_for_parent();
-	kill(getpid(), SIGSTOP);
-	exit(3);
-}
-
-#ifdef UCLINUX
-static void do_exit_uclinux(void)
-{
-	setup_sigint();
-	do_exit();
-}
-#endif
+static struct tst_test test = {
+	.tid = "waitpid13",
+	.forks_child = 1,
+	.needs_checkpoints = 1,
+	.cleanup = cleanup,
+	.test_all = waitpid_test,
+};
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 8/8] waitpid08: use the new API
  2016-07-15 14:39 [LTP] waitpid: new API Stanislav Kholmanskikh
                   ` (6 preceding siblings ...)
  2016-07-15 14:39 ` [LTP] [PATCH 7/8] waitpid13: " Stanislav Kholmanskikh
@ 2016-07-15 14:39 ` Stanislav Kholmanskikh
  7 siblings, 0 replies; 24+ messages in thread
From: Stanislav Kholmanskikh @ 2016-07-15 14:39 UTC (permalink / raw)
  To: ltp

And also use the WIFEXITED/WEXITSTATUS logic from waitpid06, 07
test cases. It seems this was the initial idea of the test's author.

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
 testcases/kernel/syscalls/waitpid/waitpid08.c |  297 +++++--------------------
 1 files changed, 55 insertions(+), 242 deletions(-)

diff --git a/testcases/kernel/syscalls/waitpid/waitpid08.c b/testcases/kernel/syscalls/waitpid/waitpid08.c
index b2e9e9b..4021441 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid08.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid08.c
@@ -1,185 +1,53 @@
 /*
+ * Copyright (c) International Business Machines  Corp., 2001
  *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * This program is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
  *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * History
+ *	07/2001 John George
+ *		-Ported
+ *      04/2002 wjhuie sigset cleanups
  */
 
 /*
- * NAME
- *	waitpid08.c
- *
  * DESCRIPTION
- *	Tests to see if pid's returned from fork and waitpid are same
+ *	Tests to see if pids returned from fork and waitpid are same.
  *
  * ALGORITHM
  *	Check proper functioning of waitpid with pid = -1 and arg =
  *	WUNTRACED
- *
- * USAGE:  <for command-line>
- *      waitpid08 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- *      where,  -c n : Run n copies concurrently.
- *              -e   : Turn on errno logging.
- *              -i n : Execute test n times.
- *              -I x : Execute test for x seconds.
- *              -P x : Pause for x seconds between iterations.
- *              -t   : Turn on syscall timing.
- *
- * History
- *	07/2001 John George
- *		-Ported
- *      04/2002 wjhuie sigset cleanups
- *
- * Restrictions
- *	None
  */
 
-#include <sys/types.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include "test.h"
-
-static void inthandlr();
-static void do_exit(void);
-static void setup_sigint(void);
-static void do_child_1(void);
-static void setup(void);
-static void cleanup(void);
-
-char *TCID = "waitpid08";
-int TST_TOTAL = 1;
-volatile int intintr;
-static int fail;
-
-#define	MAXKIDS	8
-
-#ifdef UCLINUX
-static char *argv0;
-static void do_child_2_uclinux(void);
-#endif
-
-int main(int argc, char **argv)
-{
-	int lc;
-
-	int status;
-	int pid;
-
-	tst_parse_opts(argc, argv, NULL, NULL);
-
-#ifdef UCLINUX
-	argv0 = argv[0];
-
-	maybe_run_child(&do_child_1, "n", 1);
-	maybe_run_child(&do_child_2_uclinux, "n", 2);
-#endif
-
-	setup();
-
-	/* check for looping state if -i option is given */
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-		fail = 0;
-
-		pid = FORK_OR_VFORK();
-		if (pid < 0) {
-			tst_resm(TFAIL, "Fork Failed, may be OK under stress");
-
-		} else if (pid == 0) {
-			/*
-			 * Child:
-			 * Set up to catch SIGINT.
-			 * The kids will wait till a SIGINT has been received
-			 * before they proceed.
-			 */
-#ifdef UCLINUX
-			if (self_exec(argv[0], "n", 1) < 0) {
-				tst_resm(TINFO, "self_exec failed");
-				exit(pid);
-			}
-#else
-			do_child_1();
-#endif
-		} else {	/* parent */
-			waitpid(pid, &status, 0);
-			if (WEXITSTATUS(status) != 0) {
-				tst_resm(TFAIL, "child returned bad status");
-				fail = 1;
-			}
-			if (fail)
-				tst_resm(TFAIL, "%s FAILED", TCID);
-			else
-				tst_resm(TPASS, "%s PASSED", TCID);
-		}
-	}
-
-	cleanup();
-	tst_exit();
-}
-
-/*
- * setup_sigint()
- *	Sets up a SIGINT handler
- */
-static void setup_sigint(void)
-{
-	if ((sig_t) signal(SIGINT, inthandlr) == SIG_ERR) {
-		tst_resm(TFAIL, "signal SIGINT failed. " "errno = %d", errno);
-		exit(-1);
-	}
-}
+#include "waitpid_common.h"
 
 static void do_child_1(void)
 {
-	int kid_count, fork_kid_pid[MAXKIDS];
-	int ret_val;
+	int kid_count;
+	pid_t ret_val;
 	int i, j, k, found;
-	int group1, group2;
-	int wait_kid_pid[MAXKIDS], status;
-
-	setup_sigint();
-
-	group1 = getpgrp();
+	pid_t wait_kid_pid[MAXKIDS];
+	int status;
+	int fail = 0;
 
 	for (kid_count = 0; kid_count < MAXKIDS; kid_count++) {
 		if (kid_count == (MAXKIDS / 2))
-			group2 = setpgrp();
+			SAFE_SETPGID(0, 0);
 
-		intintr = 0;
-		ret_val = FORK_OR_VFORK();
-		if (ret_val == 0) {
-#ifdef UCLINUX
-			if (self_exec(argv0, "n", 2) < 0) {
-				tst_resm(TFAIL, "Fork kid %d failed. "
-					 "errno = %d", kid_count, errno);
-				exit(ret_val);
-			}
-#else
-			do_exit();
-#endif
-		}
+		ret_val = SAFE_FORK();
+		if (ret_val == 0)
+			do_exit(0);
 
-		if (ret_val < 0) {
-			tst_resm(TFAIL, "Fork kid %d failed. "
-				 "errno = %d", kid_count, errno);
-			exit(ret_val);
-		}
-
-		/* parent */
 		fork_kid_pid[kid_count] = ret_val;
 	}
 
@@ -188,26 +56,12 @@ static void do_child_1(void)
 	 */
 	ret_val = waitpid(-1, &status, WNOHANG | WUNTRACED);
 	if (ret_val != 0) {
-		tst_resm(TFAIL, "Waitpid returned wrong value");
-		tst_resm(TFAIL, "Expected 0 got %d", ret_val);
+		tst_res(TFAIL, "Waitpid returned wrong value");
+		tst_res(TFAIL, "Expected 0 got %d", ret_val);
 		fail = 1;
 	}
-#ifdef UCLINUX
-	/* Give the kids a chance to setup SIGINT again, since this is
-	 * cleared by exec().
-	 */
-	sleep(3);
-#endif
 
-	/* Now send all the kids a SIGINT to tell them to
-	 * proceed
-	 */
-	for (i = 0; i < MAXKIDS; i++) {
-		if (kill(fork_kid_pid[i], SIGINT) < 0) {
-			tst_brkm(TFAIL, NULL, "Kill of child %d "
-				 "failed, errno = %d", i, errno);
-		}
-	}
+	TST_CHECKPOINT_WAKE2(0, MAXKIDS);
 
 	/*
 	 * Wait till all kids have terminated.  Stash away their
@@ -221,27 +75,16 @@ static void do_child_1(void)
 			continue;
 
 		if (!WIFEXITED(status)) {
-			if (!WIFSTOPPED(status)) {
-				tst_resm(TFAIL, "Child %d did "
-					 "not stopped", ret_val);
-				fail = 1;
-			} else {
-				if (WSTOPSIG(status) != SIGSTOP) {
-					tst_resm(TFAIL,
-						 "Child %d "
-						 "exited with "
-						 "wrong status", ret_val);
-					tst_resm(TFAIL,
-						 "Expected "
-						 "SIGSTOP got %d",
-						 WSTOPSIG(status));
-					fail = 1;
-				}
-			}
-			if (kill(ret_val, SIGCONT) < 0) {
-				tst_resm(TFAIL, "Kill of child "
-					 "%d failed, errno = %d",
-					 ret_val, errno);
+			tst_res(TFAIL, "Child %d did not exit "
+				 "normally", ret_val);
+			fail = 1;
+		} else {
+			if (WEXITSTATUS(status) != 3) {
+				tst_res(TFAIL, "Child %d "
+					 "exited with wrong "
+					 "status", ret_val);
+				tst_res(TFAIL, "Expected 3 "
+					 "got %d ", WEXITSTATUS(status));
 				fail = 1;
 			}
 		}
@@ -262,16 +105,16 @@ static void do_child_1(void)
 			}
 		}
 		if (!found) {
-			tst_resm(TFAIL,
+			tst_res(TFAIL,
 				 "Did not find a wait_kid_pid "
 				 "for the fork_kid_pid of %d", wait_kid_pid[i]);
 			for (k = 0; k < MAXKIDS; k++) {
-				tst_resm(TFAIL,
+				tst_res(TFAIL,
 					 "fork_kid_pid[%d] = "
 					 "%d", k, fork_kid_pid[k]);
 			}
 			for (k = 0; k < kid_count; k++) {
-				tst_resm(TFAIL,
+				tst_res(TFAIL,
 					 "wait_kid_pid[%d] = "
 					 "%d", k, wait_kid_pid[k]);
 			}
@@ -285,57 +128,27 @@ static void do_child_1(void)
 	 */
 	ret_val = waitpid(-1, &status, WUNTRACED);
 	if (ret_val != -1) {
-		tst_resm(TFAIL, "Waitpid returned wrong value.");
-		tst_resm(TFAIL, "Expected -1 got %d from "
+		tst_res(TFAIL, "Waitpid returned wrong value.");
+		tst_res(TFAIL, "Expected -1 got %d from "
 			 "waitpid(WUNTRACED)", ret_val);
 		fail = 1;
 	}
 
 	if (errno != ECHILD) {
-		tst_resm(TFAIL, "Waitpid returned wrong errno.");
-		tst_resm(TFAIL, "Expected ECHILD got %d", errno);
+		tst_res(TFAIL, "Waitpid returned wrong errno.");
+		tst_res(TFAIL, "Expected ECHILD got %d", errno);
 		fail = 1;
 	}
 
-	exit(fail);
-}
+	memset(fork_kid_pid, 0, sizeof(*fork_kid_pid) * MAXKIDS);
 
-#ifdef UCLINUX
-/*
- * do_child_2_uclinux()
- *	sets up sigint handler again, then calls the normal child 2 function
- */
-static void do_child_2_uclinux(void)
-{
-	setup_sigint();
-	do_exit();
-}
-#endif
-
-static void setup(void)
-{
-	TEST_PAUSE;
-}
-
-static void cleanup(void)
-{
-}
-
-static void inthandlr(void)
-{
-	intintr++;
-}
-
-static void wait_for_parent(void)
-{
-	int testvar;
-
-	while (!intintr)
-		testvar = 0;
+	exit(fail);
 }
 
-static void do_exit(void)
-{
-	wait_for_parent();
-	exit(3);
-}
+static struct tst_test test = {
+	.tid = "waitpid08",
+	.forks_child = 1,
+	.needs_checkpoints = 1,
+	.cleanup = cleanup,
+	.test_all = waitpid_test,
+};
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 2/8] waitpid06: use the new API
  2016-07-15 14:39 ` [LTP] [PATCH 2/8] waitpid06: use the new API Stanislav Kholmanskikh
@ 2016-07-18 13:05   ` Cyril Hrubis
  2016-07-19 14:55     ` [LTP] [PATCH V2 1/4] " Stanislav Kholmanskikh
  2016-08-03 10:19     ` [LTP] [PATCH 2/8] " Stanislav Kholmanskikh
  0 siblings, 2 replies; 24+ messages in thread
From: Cyril Hrubis @ 2016-07-18 13:05 UTC (permalink / raw)
  To: ltp

Hi!
> -#include <sys/types.h>
> -#include <signal.h>
> -#include <errno.h>
> -#include <sys/wait.h>
> -#include "test.h"
> -
> -static void setup_sigint(void);
> -static void do_child_1(void);
> -static void setup(void);
> -static void cleanup(void);
> -
> -char *TCID = "waitpid06";
> -int TST_TOTAL = 1;
> -volatile int intintr;
> -static void inthandlr();
> -static void do_exit(void);
> -static int flag;
> -
> -#define	FAILED	1
> -#define	MAXKIDS	8
> -
> -#ifdef UCLINUX
> -static char *argv0;
> -static void do_child_2_uclinux(void);
> -#endif
> -
> -int main(int argc, char **argv)
> -{
> -	int lc;
> -	int fail = 0;
> -	int pid;
> -	int status;
> -
> -	tst_parse_opts(argc, argv, NULL, NULL);
> -
> -#ifdef UCLINUX
> -	argv0 = argv[0];
> -
> -	maybe_run_child(&do_child_1, "n", 1);
> -	maybe_run_child(&do_child_2_uclinux, "n", 2);
> -#endif
> -
> -	setup();
> -
> -	for (lc = 0; TEST_LOOPING(lc); lc++) {
> -		/* reset tst_count in case we are looping */
> -		tst_count = 0;
> -
> -		pid = FORK_OR_VFORK();
> -		if (pid < 0) {
> -			tst_resm(TINFO, "Fork Failed, may be OK under stress");
> -			exit(pid);
> -		} else if (pid == 0) {
> -			/*
> -			 * Child:
> -			 * Set up to catch SIGINT.  The kids will wait till a
> -			 * SIGINT has been received before they proceed.
> -			 */
> -#ifdef UCLINUX
> -			if (self_exec(argv[0], "n", 1) < 0) {
> -				tst_resm(TINFO, "self_exec failed");
> -				exit(pid);
> -			}
> -#else
> -			do_child_1();
> -#endif
> -		} else {	/* parent */
> -			fail = 0;
> -			waitpid(pid, &status, 0);
> -			if (WEXITSTATUS(status) != 0) {
> -				tst_resm(TFAIL, "child returned bad status");
> -				fail = 1;
> -			}
> -			if (fail)
> -				tst_resm(TFAIL, "%s FAILED", TCID);
> -			else
> -				tst_resm(TPASS, "%s PASSED", TCID);
> -		}
> -	}
> -
> -	cleanup();
> -	tst_exit();
> -}
> -
> -/*
> - * setup_sigint()
> - *	Sets up a SIGINT handler
> - */
> -static void setup_sigint(void)
> -{
> -	if ((sig_t) signal(SIGINT, inthandlr) == SIG_ERR) {
> -		tst_resm(TFAIL, "signal SIGINT failed. " "errno = %d", errno);
> -		exit(-1);
> -	}
> -}
> +#include "waitpid_common.h"
>  
>  static void do_child_1(void)
>  {
> -	int kid_count, fork_kid_pid[MAXKIDS];
> -	int ret_val;
> +	int kid_count;
> +	pid_t ret_val;
>  	int i, j, k, found;
> -	int group1, group2;
> -	int wait_kid_pid[MAXKIDS], status;
> -
> -	setup_sigint();
> +	pid_t wait_kid_pid[MAXKIDS];
> +	int status;
> +	int flag = 0;
>  
> -	group1 = getpgrp();
>  	for (kid_count = 0; kid_count < MAXKIDS; kid_count++) {
>  		if (kid_count == (MAXKIDS / 2))
> -			group2 = setpgrp();
> +			SAFE_SETPGID(0, 0);
>  
> -		intintr = 0;
> -		ret_val = FORK_OR_VFORK();
> -		if (ret_val == 0) {	/* child */
> -#ifdef UCLINUX
> -			if (self_exec(argv0, "n", 2) < 0) {
> -				tst_resm(TFAIL, "Fork kid %d failed. "
> -					 "errno = %d", kid_count, errno);
> -				exit(ret_val);
> -			}
> -#else
> -			do_exit();
> -#endif
> -		} else if (ret_val < 0) {
> -			tst_resm(TFAIL, "Fork kid %d failed. "
> -				 "errno = %d", kid_count, errno);
> -			exit(ret_val);
> -		}
> +		ret_val = SAFE_FORK();
> +		if (ret_val == 0)
> +			do_exit(0);
>  
> -		/* parent */
>  		fork_kid_pid[kid_count] = ret_val;

>  	}
>  
> -#ifdef UCLINUX
> -	/* Give the kids a chance to setup SIGINT again, since this is
> -	 * cleared by exec().
> -	 */
> -	sleep(3);
> -#endif
> -
> -	/* Now send all the kids a SIGINT to tell them to
> -	 * proceed
> -	 */
> -	for (i = 0; i < MAXKIDS; i++) {
> -		if (kill(fork_kid_pid[i], SIGINT) < 0) {
> -			tst_resm(TFAIL, "Kill of child %d "
> -				 "failed, errno = %d", i, errno);
> -			exit(-1);
> -		}
> -	}
> +	TST_CHECKPOINT_WAKE2(0, MAXKIDS);
>  
>  	/*
>  	 * Wait till all kids have terminated.  Stash away their
> -	 * pid's in an array.
> +	 * pids in an array.
>  	 */
>  	kid_count = 0;
>  	errno = 0;
> @@ -207,16 +63,15 @@ static void do_child_1(void)
>  			continue;
>  
>  		if (!WIFEXITED(status)) {
> -			tst_resm(TFAIL, "Child %d did not exit "
> +			tst_res(TFAIL, "Child %d did not exit "
>  				 "normally", ret_val);
>  			flag = FAILED;
> -			printf("status: %d\n", status);
>  		} else {
>  			if (WEXITSTATUS(status) != 3) {
> -				tst_resm(TFAIL, "Child %d"
> +				tst_res(TFAIL, "Child %d "
>  					 "exited with wrong "
>  					 "status", ret_val);
> -				tst_resm(TFAIL, "Expected 3 "
> +				tst_res(TFAIL, "Expected 3 "
>  					 "got %d ", WEXITSTATUS(status));
>  				flag = FAILED;
>  			}
> @@ -239,16 +94,16 @@ static void do_child_1(void)
>  		}
>  
>  		if (!found) {
> -			tst_resm(TFAIL, "Did not find a "
> +			tst_res(TFAIL, "Did not find a "
>  				 "wait_kid_pid for the "
>  				 "fork_kid_pid of %d", wait_kid_pid[i]);
>  			for (k = 0; k < MAXKIDS; k++) {
> -				tst_resm(TFAIL,
> +				tst_res(TFAIL,
>  					 "fork_kid_pid[%d] = "
>  					 "%d", k, fork_kid_pid[k]);
>  			}
>  			for (k = 0; k < kid_count; k++) {
> -				tst_resm(TFAIL,
> +				tst_res(TFAIL,
>  					 "wait_kid_pid[%d] = "
>  					 "%d", k, wait_kid_pid[k]);

This should probably be TINFO rather than TFAIL.

> +	exit(flag);
>  }

The TFAIL should be propagated automatically (the test results are
stored in shared memory in newlib), we can drop the whole logic around
the flag and exit value.

> -static void do_exit(void)
> -{
> -	wait_for_parent();
> -	exit(3);
> -}
> +static struct tst_test test = {
> +	.tid = "waitpid06",
> +	.forks_child = 1,
> +	.needs_checkpoints = 1,
> +	.cleanup = cleanup,
> +	.test_all = waitpid_test,
> +};
> diff --git a/testcases/kernel/syscalls/waitpid/waitpid_common.h b/testcases/kernel/syscalls/waitpid/waitpid_common.h
> new file mode 100644
> index 0000000..909468a
> --- /dev/null
> +++ b/testcases/kernel/syscalls/waitpid/waitpid_common.h
> @@ -0,0 +1,78 @@
> +/*
> + * Copyright (c) 2016 Linux Test Project
> + *
> + * Licensed under the GNU GPLv2 or later.
> + * This program is free software;  you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY;  without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
> + * the GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.
> + */
> +
> +#ifndef WAITPID_COMMON_H__
> +#define WAITPID_COMMON_H__
> +
> +#include <sys/types.h>
> +#include <errno.h>
> +#include <sys/wait.h>
> +#include <stdlib.h>
> +#include "tst_test.h"
> +
> +#define	FAILED	1
> +#define	MAXKIDS	8
> +
> +static pid_t *fork_kid_pid;
> +
> +static void do_child_1(void);
> +
> +static void cleanup(void)
> +{
> +	int i;
> +
> +	for (i = 0; i < MAXKIDS; i++) {
> +		if (fork_kid_pid[i] > 0) {
> +			kill(fork_kid_pid[i], SIGKILL);
> +			waitpid(fork_kid_pid[i], NULL, 0);
> +		}
> +	}

We should kill the pid of the do_child_1() here as well.

And possibly unmap the shared memory.

> +}
> +
> +static void waitpid_test(void)
> +{
> +	pid_t pid;
> +	int status;
> +
> +	fork_kid_pid = SAFE_MMAP(NULL, sizeof(*fork_kid_pid) * MAXKIDS,
> +				 PROT_READ | PROT_WRITE,
> +				 MAP_SHARED | MAP_ANONYMOUS, -1, 0);

So we allocate shared memory here so that we can kill all the children
from the main test process. That's fine, but this should be done in the
setup() rather than in the test() function. Since otherwise this will
allocate the memory on each iteration of the test.

Also there is a race condition since we wait() on the pid, then do
various checks, then finally clear the array. We should rather clear the
pid from the shared array right after we return from the wait() and keep
a copy of the array for the checks.

Or we can zero the pid from the array the moment we get it from
waitpid() and also produce failure if particular pid couldn't be found.

Something as:

	for (;;) {
		pid = waitpid(-1, &status, 0);

		if (pid < 0) {
			if (errno == EINTR)
				continue;

			break;
		}

		for (i = 0; i < MAXKIDS; i++) {
			if (pid == pids[i]) {
				pids[i] = 0;
				break;
			}
		}

		if (i == MAXKIDS)
			tst_res(TFAIL, "Pid %i not found...", pid);

		if (!WIFEXITED(status))
			tst_res(TFAIL, "Pid %i returned with %i", pid, status);
	}

	for (i = 0; i < MAXKIDS; i++) {
		if (pids[i])
			tst_res(TFAIL, "Pid %i not reaped", pids[i]);
	}

> +	pid = SAFE_FORK();
> +	if (pid == 0) {
> +		do_child_1();
> +	} else {
> +		SAFE_WAITPID(pid, &status, 0);
> +		if (WEXITSTATUS(status) != 0)
> +			tst_res(TFAIL, "Child returned bad status");
> +		else
> +			tst_res(TPASS, "Child returned good status");
> +	}

Here as well, the test result is already in the shared memory.

We should check here if the child wasn't killed at this point though.
Something as:

	if (!WIFEXITED(status))
		tst_brk(TBROK, "Child exited abnormally");

> +}
> +
> +static void do_exit(int stop)
> +{
> +	TST_CHECKPOINT_WAIT(0);
> +
> +	if (stop)
> +		kill(getpid(), SIGSTOP);
> +
> +	exit(3);
> +}
> +
> +#endif /* WAITPID_COMMON_H__ */
> -- 
> 1.7.1
> 
> 
> -- 
> Mailing list info: https://lists.linux.it/listinfo/ltp

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 4/8] waitpid09: use the new API
  2016-07-15 14:39 ` [LTP] [PATCH 4/8] waitpid09: " Stanislav Kholmanskikh
@ 2016-07-18 14:18   ` Cyril Hrubis
  2016-07-19 10:34     ` [LTP] [PATCH V2 " Stanislav Kholmanskikh
  0 siblings, 1 reply; 24+ messages in thread
From: Cyril Hrubis @ 2016-07-18 14:18 UTC (permalink / raw)
  To: ltp

Hi!
> +static void case0(void)
> +{
> +	pid_t ret;
> +	int status;
> +	int fail = 0;
> +
> +	pid = SAFE_FORK();
> +	if (pid == 0)
> +		do_exit();
> +
> +	/*
> +	 *Check that waitpid with WNOHANG returns zero
> +	 */
> +	while (((ret = waitpid(pid, &status, WNOHANG))
> +		!= 0) || (errno == EINTR)) {
> +		if (ret == -1)
> +			continue;
> +
> +		tst_res(TFAIL, "return value for "
> +			 "WNOHANG expected 0 got %d",
> +			 ret);
> +		fail = 1;
> +	}
>  
> -				while (((ret = waitpid(pid, &status, WNOHANG))
> -					!= -1) || (errno == EINTR)) {
> -					if (ret == -1)
> -						continue;
> +	TST_CHECKPOINT_WAKE(0);
>  
> -					if (ret != pid) {
> -						tst_resm(TFAIL, "proc id %d "
> -							 "and retval %d do not "
> -							 "match", pid, ret);
> -						fail = 1;
> -					}
> +	while (((ret = waitpid(pid, &status, 0)) != -1)
> +	       || (errno == EINTR)) {
> +		if (ret == -1)
> +			continue;
>  
> -					if (status != 0) {
> -						tst_resm(TFAIL, "non zero "
> -							 "status received %d",
> -							 status);
> -						fail = 1;
> -					}
> -				}
> -			}
> +		if (ret != pid) {
> +			tst_res(TFAIL, "Expected %d "
> +				 "got %d as proc id of "
> +				 "child", pid, ret);
> +			fail = 1;
> +		}
>  
> -			if (fail)
> -				tst_resm(TFAIL, "case 1 FAILED");
> -			else
> -				tst_resm(TPASS, "case 1 PASSED");
> +		if (status != 0) {
> +			tst_res(TFAIL, "status value "
> +				 "got %d expected 0",
> +				 status);
> +			fail = 1;
> +		}
> +	}
>  
> -			fail = 0;
> -			ret = waitpid(pid, &status, 0);
> +	pid = 0;
>  
> -			if (ret != -1) {
> -				tst_resm(TFAIL, "Expected -1 got %d", ret);
> -				fail = 1;
> -			}
> -			if (errno != ECHILD) {
> -				tst_resm(TFAIL, "Expected ECHILD got %d",
> -					 errno);
> -				fail = 1;
> -			}
> +	pid = SAFE_FORK();
> +	if (pid == 0)
> +		exit(0);
>  
> -			ret = waitpid(pid, &status, WNOHANG);
> -			if (ret != -1) {
> -				tst_resm(TFAIL, "WNOHANG: Expected -1 got %d",
> -					 ret);
> -				fail = 1;
> -			}
> -			if (errno != ECHILD) {
> -				tst_resm(TFAIL, "WNOHANG: Expected ECHILD got "
> -					 "%d", errno);
> -				fail = 1;
> -			}
> +	while (((ret = waitpid(pid, &status, WNOHANG))
> +		!= -1) || (errno == EINTR)) {
> +		if (ret == -1)
> +			continue;
> +		if (ret == 0)
> +			continue;
>  
> -			if (fail)
> -				tst_resm(TFAIL, "case 2 FAILED");
> -			else
> -				tst_resm(TPASS, "case 2 PASSED");
> +		if (ret != pid) {
> +			tst_res(TFAIL, "proc id %d "
> +				 "and retval %d do not "
> +				 "match", pid, ret);
> +			fail = 1;
>  		}
>  
> -		cleanup();
> -	} else {
> -		/* wait for the child to return */
> -		waitpid(pid, &status, 0);
> -		if (WEXITSTATUS(status) != 0) {
> -			tst_brkm(TBROK, cleanup, "child returned bad "
> -				 "status");
> +		if (status != 0) {
> +			tst_res(TFAIL, "non zero "
> +				 "status received %d",
> +				 status);
> +			fail = 1;
>  		}
>  	}
>  
> -	tst_exit();
> +	pid = 0;
> +
> +	if (fail)
> +		tst_res(TFAIL, "case 0 FAILED");
> +	else
> +		tst_res(TPASS, "case 0 PASSED");
>  }

Both of the case0 and case1 can be easily further split into two
testcases, then we can get rid of the fail flag as well (do a return in
case of a failure and do TPASS on the last line of the test function).

> -/*
> - * setup_sigint()
> - *	sets up a SIGINT handler
> - */
> -static void setup_sigint(void)
> +static void case1(void)
>  {
> -	if ((sig_t) signal(SIGINT, inthandlr) == SIG_ERR) {
> -		tst_brkm(TFAIL, cleanup, "signal SIGINT failed, errno = %d",
> +	pid_t ret;
> +	int status;
> +	int fail = 0;
> +
> +	ret = waitpid(-1, &status, 0);
> +
> +	if (ret != -1) {
> +		tst_res(TFAIL, "Expected -1 got %d", ret);
> +		fail = 1;
> +	}
> +	if (errno != ECHILD) {
> +		tst_res(TFAIL, "Expected ECHILD got %d",
>  			 errno);
> +		fail = 1;
>  	}
> -}
> -
> -static void setup(void)
> -{
> -	TEST_PAUSE;
> -}
>  
> -static void cleanup(void)
> -{
> -}
> +	ret = waitpid(-1, &status, WNOHANG);
> +	if (ret != -1) {
> +		tst_res(TFAIL, "WNOHANG: Expected -1 got %d",
> +			 ret);
> +		fail = 1;
> +	}
> +	if (errno != ECHILD) {
> +		tst_res(TFAIL, "WNOHANG: Expected ECHILD got "
> +			 "%d", errno);
> +		fail = 1;
> +	}
>  
> -static void inthandlr(void)
> -{
> -	intintr++;
> +	if (fail)
> +		tst_res(TFAIL, "case 1 FAILED");
> +	else
> +		tst_res(TPASS, "case 1 PASSED");
>  }
>  
> -static void wait_for_parent(void)
> +static void waitpid09_test(unsigned int id)
>  {
> -	int testvar;
> -	while (!intintr)
> -		testvar = 0;
> +	switch (id) {
> +	case 0:
> +		case0();
> +		break;
> +	case 1:
> +		case1();
> +		break;
> +	default:
> +		tst_brk(TBROK, "Unknown %d", id);
> +	}
>  }
>  
>  static void do_exit(void)
>  {
> -	wait_for_parent();
> +	TST_CHECKPOINT_WAIT(0);
> +
>  	exit(0);
>  }

Since UCLINUX support was removed it does not make any sense to keep
this code in a function anymore...

> -#ifdef UCLINUX
> -/*
> - * do_exit_uclinux()
> - *	Sets up SIGINT handler again, then calls do_exit
> - */
> -static void do_exit_uclinux(void)
> -{
> -	setup_sigint();
> -	do_exit();
> -}
> -#endif
> +static struct tst_test test = {
> +	.tid = "waitpid09",
> +	.forks_child = 1,
> +	.needs_checkpoints = 1,
> +	.cleanup = cleanup,
> +	.test = waitpid09_test,
> +	.tcnt = 2,
> +};

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 5/8] waitpid11: use the new API
  2016-07-15 14:39 ` [LTP] [PATCH 5/8] waitpid11: " Stanislav Kholmanskikh
@ 2016-07-18 15:01   ` Cyril Hrubis
  0 siblings, 0 replies; 24+ messages in thread
From: Cyril Hrubis @ 2016-07-18 15:01 UTC (permalink / raw)
  To: ltp

Hi!
This test does nearly the same as waitpid06, but here we pick up the
children by the process group instead of getting them all with -1 as a
pid.

I guess that we could create a function that would take an array of
pids, it's lenght and waitpid pid parameter and would assert that all
children pids in the array could be waited for. Then we could reuse the
function in waitpid06 passing whole array and -1 and here passing first
half of the array and 0 then second half of the array and -group...

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 6/8] waitpid12: use the new API
  2016-07-15 14:39 ` [LTP] [PATCH 6/8] waitpid12: " Stanislav Kholmanskikh
@ 2016-07-18 15:07   ` Cyril Hrubis
  0 siblings, 0 replies; 24+ messages in thread
From: Cyril Hrubis @ 2016-07-18 15:07 UTC (permalink / raw)
  To: ltp

Hi!
And I guess that this test can be simplified quite a lot, there is no
reason for checking that pids could be waited for by process group etc.
We only care about the WNOHANG here (since the rest of the code is
nearly identical to waitpid11.c).

All that needs to be done here is to fork some number of children in a
test setup and let them sleep (I would use pause() for simplicity). Then
the whole test would be just a call to waitpid() with WNOHANG and the
test cleanup would send a signal to the test childrens and then wait for
them.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH V2 4/8] waitpid09: use the new API
  2016-07-18 14:18   ` Cyril Hrubis
@ 2016-07-19 10:34     ` Stanislav Kholmanskikh
  2016-07-19 12:41       ` Cyril Hrubis
  0 siblings, 1 reply; 24+ messages in thread
From: Stanislav Kholmanskikh @ 2016-07-19 10:34 UTC (permalink / raw)
  To: ltp

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
Hi!

Thank you for review of V1.

This patch addresses all your comments, except the one about do_exit(),
because do_exit() is required for case 0.


testcases/kernel/syscalls/waitpid/waitpid09.c |  435 ++++++++++---------------
 1 files changed, 178 insertions(+), 257 deletions(-)

diff --git a/testcases/kernel/syscalls/waitpid/waitpid09.c b/testcases/kernel/syscalls/waitpid/waitpid09.c
index 1339c82..6331b19 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid09.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid09.c
@@ -1,57 +1,37 @@
 /*
+ * Copyright (c) International Business Machines  Corp., 2001
  *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * This program is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
  *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * NAME
- *	waitpid09.c
- *
- * DESCRIPTION
- *	Check ability of parent to wait until child returns, and that the
- *	child's process id is returned through the waitpid. Check that
- *	waitpid returns immediately if no child is present.
- *
- * ALGORITHM
- *	case 0:
- *		Parent forks a child and waits. Parent should do nothing
- *		further until child returns. The pid of the forked child
- *		should match the returned value from the waitpid.
- *
- *	case 1:
- *		Parent calls a waitpid with no children waiting. Waitpid
- *		should return a -1 since there are no children to wait for.
- *
- * USAGE:  <for command-line>
- *      waitpid09 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- *      where,  -c n : Run n copies concurrently.
- *              -e   : Turn on errno logging.
- *              -i n : Execute test n times.
- *              -I x : Execute test for x seconds.
- *              -P x : Pause for x seconds between iterations.
- *              -t   : Turn on syscall timing.
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
  *
  * History
  *	07/2001 John George
  *		-Ported
  *      04/2002 wjhuie sigset cleanups
- *
- * Restrictions
- *	None
+ */
+
+/*
+ * case 0:
+ *        waitpid(pid, WNOHANG) should return 0 if there is a running child
+ * case 1:
+ *        waitpid(pid, WNOHANG) should return the pid of the child if
+ *        the child has exited
+ * case 2:
+ *        waitpid(-1, 0) should return -1 with ECHILD if
+ *        there are no children to wait for.
+ * case 3:
+ *        waitpid(-1, WNOHANG) should return -1 with ECHILD if
+ *        there are no children to wait for.
  */
 
 #define _GNU_SOURCE 1
@@ -60,243 +40,184 @@
 #include <errno.h>
 #include <sys/wait.h>
 #include <stdlib.h>
+#include "tst_test.h"
 
-#include "test.h"
-
-char *TCID = "waitpid09";
-int TST_TOTAL = 1;
-volatile int intintr;
-
-static void setup(void);
-static void cleanup(void);
-static void inthandlr();
 static void do_exit(void);
-static void setup_sigint(void);
-#ifdef UCLINUX
-static void do_exit_uclinux(void);
-#endif
 
-int main(int argc, char **argv)
+static void cleanup_pid(pid_t pid)
 {
-	int lc;
-
-	int fail, pid, status, ret;
-
-	tst_parse_opts(argc, argv, NULL, NULL);
-
-#ifdef UCLINUX
-	maybe_run_child(&do_exit_uclinux, "");
-#endif
-
-	setup();
-
-	pid = FORK_OR_VFORK();
-	if (pid < 0) {
-		tst_brkm(TFAIL, cleanup, "Fork Failed");
-	} else if (pid == 0) {
-		/*
-		 * Child:
-		 * Set up to catch SIGINT.  The kids will wait till a
-		 * SIGINT has been received before they proceed.
-		 */
-		setup_sigint();
-
-		/* check for looping state if -i option is given */
-		for (lc = 0; TEST_LOOPING(lc); lc++) {
-			/* reset tst_count in case we are looping */
-			tst_count = 0;
-
-			intintr = 0;
-
-			fail = 0;
-			pid = FORK_OR_VFORK();
-			if (pid < 0) {
-				tst_brkm(TFAIL, cleanup, "Fork failed.");
-			} else if (pid == 0) {	/* child */
-#ifdef UCLINUX
-				if (self_exec(argv[0], "") < 0) {
-					tst_brkm(TFAIL, cleanup,
-						 "self_exec failed");
-				}
-#else
-				do_exit();
-#endif
-			} else {	/* parent */
-
-				/*
-				 *Check that waitpid with WNOHANG returns zero
-				 */
-				while (((ret = waitpid(pid, &status, WNOHANG))
-					!= 0) || (errno == EINTR)) {
-					if (ret == -1)
-						continue;
-
-					tst_resm(TFAIL, "return value for "
-						 "WNOHANG expected 0 got %d",
-						 ret);
-					fail = 1;
-				}
-#ifdef UCLINUX
-				/* Give the kids a chance to setup SIGINT again, since
-				 * this is cleared by exec().
-				 */
-				sleep(3);
-#endif
-
-				/* send SIGINT to child to tell it to proceed */
-				if (kill(pid, SIGINT) < 0) {
-					tst_resm(TFAIL, "Kill of child failed, "
-						 "errno = %d", errno);
-					fail = 1;
-				}
-
-				while (((ret = waitpid(pid, &status, 0)) != -1)
-				       || (errno == EINTR)) {
-					if (ret == -1)
-						continue;
-
-					if (ret != pid) {
-						tst_resm(TFAIL, "Expected %d "
-							 "got %d as proc id of "
-							 "child", pid, ret);
-						fail = 1;
-					}
-
-					if (status != 0) {
-						tst_resm(TFAIL, "status value "
-							 "got %d expected 0",
-							 status);
-						fail = 1;
-					}
-				}
-			}
-
-			pid = FORK_OR_VFORK();
-			if (pid < 0) {
-				tst_brkm(TFAIL, cleanup, "Second fork failed.");
-			} else if (pid == 0) {	/* child */
-				exit(0);
-			} else {	/* parent */
-				/* Give the child time to startup and exit */
-				sleep(2);
-
-				while (((ret = waitpid(pid, &status, WNOHANG))
-					!= -1) || (errno == EINTR)) {
-					if (ret == -1)
-						continue;
-
-					if (ret != pid) {
-						tst_resm(TFAIL, "proc id %d "
-							 "and retval %d do not "
-							 "match", pid, ret);
-						fail = 1;
-					}
-
-					if (status != 0) {
-						tst_resm(TFAIL, "non zero "
-							 "status received %d",
-							 status);
-						fail = 1;
-					}
-				}
-			}
-
-			if (fail)
-				tst_resm(TFAIL, "case 1 FAILED");
-			else
-				tst_resm(TPASS, "case 1 PASSED");
-
-			fail = 0;
-			ret = waitpid(pid, &status, 0);
-
-			if (ret != -1) {
-				tst_resm(TFAIL, "Expected -1 got %d", ret);
-				fail = 1;
-			}
-			if (errno != ECHILD) {
-				tst_resm(TFAIL, "Expected ECHILD got %d",
-					 errno);
-				fail = 1;
-			}
-
-			ret = waitpid(pid, &status, WNOHANG);
-			if (ret != -1) {
-				tst_resm(TFAIL, "WNOHANG: Expected -1 got %d",
-					 ret);
-				fail = 1;
-			}
-			if (errno != ECHILD) {
-				tst_resm(TFAIL, "WNOHANG: Expected ECHILD got "
-					 "%d", errno);
-				fail = 1;
-			}
-
-			if (fail)
-				tst_resm(TFAIL, "case 2 FAILED");
-			else
-				tst_resm(TPASS, "case 2 PASSED");
-		}
-
-		cleanup();
-	} else {
-		/* wait for the child to return */
-		waitpid(pid, &status, 0);
-		if (WEXITSTATUS(status) != 0) {
-			tst_brkm(TBROK, cleanup, "child returned bad "
-				 "status");
-		}
+	if (pid > 0) {
+		kill(pid, SIGKILL);
+		waitpid(pid, NULL, 0);
 	}
-
-	tst_exit();
 }
 
-/*
- * setup_sigint()
- *	sets up a SIGINT handler
- */
-static void setup_sigint(void)
+static void case0(void)
 {
-	if ((sig_t) signal(SIGINT, inthandlr) == SIG_ERR) {
-		tst_brkm(TFAIL, cleanup, "signal SIGINT failed, errno = %d",
-			 errno);
+	pid_t pid, ret;
+	int status;
+
+	pid = SAFE_FORK();
+	if (pid == 0)
+		do_exit();
+
+	for (;;) {
+		ret = waitpid(pid, &status, WNOHANG);
+
+		if ((ret == -1) && (errno == EINTR))
+			continue;
+
+		if (ret == 0)
+			break;
+
+		tst_res(TFAIL, "waitpid(WNOHANG) returned %d, expected 0",
+			ret);
+		cleanup_pid(pid);
+		return;
+	}
+
+	TST_CHECKPOINT_WAKE(0);
+
+	for (;;) {
+		ret = waitpid(pid, &status, 0);
+
+		if ((ret == -1) && (errno == EINTR))
+			continue;
+
+		if (ret == pid)
+			break;
+
+		tst_res(TFAIL, "waitpid(0) returned %d, expected %d",
+			 ret, pid);
+		cleanup_pid(pid);
+		return;
+	}
+
+	if (!WIFEXITED(status)) {
+		tst_res(TFAIL, "Child exited abnormally");
+		return;
+	}
+
+	if (WEXITSTATUS(status) != 0) {
+		tst_res(TFAIL, "Child exited with %d, expected 0",
+			WEXITSTATUS(status));
+		return;
 	}
+
+	tst_res(TPASS, "Case 0 PASSED");
 }
 
-static void setup(void)
+static void case1(void)
 {
-	TEST_PAUSE;
+	pid_t pid, ret;
+	int status;
+
+	pid = SAFE_FORK();
+	if (pid == 0)
+		exit(0);
+
+	for (;;) {
+		ret = waitpid(pid, &status, WNOHANG);
+
+		if ((ret == -1) && (errno == EINTR))
+			continue;
+		if (ret == 0)
+			continue;
+
+		if (ret == pid)
+			break;
+
+		tst_res(TFAIL, "waitpid(WNOHANG) returned %d, expected %d",
+			ret, pid);
+		cleanup_pid(pid);
+		return;
+	}
+
+	if (!WIFEXITED(status)) {
+		tst_res(TFAIL, "Child exited abnormally");
+		return;
+	}
+
+	if (WEXITSTATUS(status) != 0) {
+		tst_res(TFAIL, "Child exited with %d, expected 0",
+			WEXITSTATUS(status));
+		return;
+	}
+
+	tst_res(TPASS, "Case 1 PASSED");
 }
 
-static void cleanup(void)
+static void case2(void)
 {
+	pid_t ret;
+	int status;
+
+	ret = waitpid(-1, &status, 0);
+
+	if (ret != -1) {
+		tst_res(TFAIL, "Expected -1 got %d", ret);
+		return;
+	}
+	if (errno != ECHILD) {
+		tst_res(TFAIL, "Expected ECHILD got %d",
+			 errno);
+		return;
+	}
+
+	tst_res(TPASS, "Case 2 PASSED");
 }
 
-static void inthandlr(void)
+static void case3(void)
 {
-	intintr++;
+	pid_t ret;
+	int status;
+
+	ret = waitpid(-1, &status, WNOHANG);
+	if (ret != -1) {
+		tst_res(TFAIL, "WNOHANG: Expected -1 got %d",
+			 ret);
+		return;
+	}
+	if (errno != ECHILD) {
+		tst_res(TFAIL, "WNOHANG: Expected ECHILD got "
+			 "%d", errno);
+		return;
+	}
+
+	tst_res(TPASS, "Case 3 PASSED");
 }
 
-static void wait_for_parent(void)
+static void waitpid09_test(unsigned int id)
 {
-	int testvar;
-	while (!intintr)
-		testvar = 0;
+	switch (id) {
+	case 0:
+		case0();
+		break;
+	case 1:
+		case1();
+		break;
+	case 2:
+		case2();
+		break;
+	case 3:
+		case3();
+		break;
+	default:
+		tst_brk(TBROK, "Unknown %d", id);
+	}
 }
 
 static void do_exit(void)
 {
-	wait_for_parent();
+	TST_CHECKPOINT_WAIT(0);
+
 	exit(0);
 }
 
-#ifdef UCLINUX
-/*
- * do_exit_uclinux()
- *	Sets up SIGINT handler again, then calls do_exit
- */
-static void do_exit_uclinux(void)
-{
-	setup_sigint();
-	do_exit();
-}
-#endif
+static struct tst_test test = {
+	.tid = "waitpid09",
+	.forks_child = 1,
+	.needs_checkpoints = 1,
+	.test = waitpid09_test,
+	.tcnt = 4,
+};
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [LTP] [PATCH V2 4/8] waitpid09: use the new API
  2016-07-19 10:34     ` [LTP] [PATCH V2 " Stanislav Kholmanskikh
@ 2016-07-19 12:41       ` Cyril Hrubis
  2016-07-19 14:57         ` Stanislav Kholmanskikh
  0 siblings, 1 reply; 24+ messages in thread
From: Cyril Hrubis @ 2016-07-19 12:41 UTC (permalink / raw)
  To: ltp

Hi!
> This patch addresses all your comments, except the one about do_exit(),
> because do_exit() is required for case 0.

What I meant was to move the two lines that are in do_exit() to the if
in the case0(). Previously the function was called from two places (one
was the uclinux maybe_run_child and another one was after the fork) but
now it does not make any sense to keep it as a separate function if it's
called only from one place in the code.

Or is there another reason to keep it in a fucntion I don't see?

> +static void case2(void)
>  {
> +	pid_t ret;
> +	int status;
> +
> +	ret = waitpid(-1, &status, 0);
> +
> +	if (ret != -1) {
> +		tst_res(TFAIL, "Expected -1 got %d", ret);
> +		return;
> +	}
> +	if (errno != ECHILD) {
> +		tst_res(TFAIL, "Expected ECHILD got %d",
> +			 errno);
                        ^
			You should print the human-readable string
			returned by tst_strerrno() here as well or
			use TERRNO to have it printed by the library.

> +		return;
> +	}
> +
> +	tst_res(TPASS, "Case 2 PASSED");
>  }
>  
> -static void inthandlr(void)
> +static void case3(void)
>  {
> -	intintr++;
> +	pid_t ret;
> +	int status;
> +
> +	ret = waitpid(-1, &status, WNOHANG);
> +	if (ret != -1) {
> +		tst_res(TFAIL, "WNOHANG: Expected -1 got %d",
> +			 ret);
> +		return;
> +	}
> +	if (errno != ECHILD) {
> +		tst_res(TFAIL, "WNOHANG: Expected ECHILD got "
> +			 "%d", errno);

                        Here as well.

> +		return;
> +	}
> +
> +	tst_res(TPASS, "Case 3 PASSED");
>  }
>  
> -static void wait_for_parent(void)

Otherwise it looks good. Acked with the minor changes fixed.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH V2 1/4] waitpid06: use the new API
  2016-07-18 13:05   ` Cyril Hrubis
@ 2016-07-19 14:55     ` Stanislav Kholmanskikh
  2016-07-19 14:55       ` [LTP] [PATCH V2 2/4] waitpid07: " Stanislav Kholmanskikh
  2016-08-03 16:01       ` [LTP] [PATCH V2 1/4] waitpid06: " Cyril Hrubis
  2016-08-03 10:19     ` [LTP] [PATCH 2/8] " Stanislav Kholmanskikh
  1 sibling, 2 replies; 24+ messages in thread
From: Stanislav Kholmanskikh @ 2016-07-19 14:55 UTC (permalink / raw)
  To: ltp

 * Use the new LTP API
 * Use the checkpoint interface instead of wait_for_parent()
 * Drop UCLINUX support

Common items were moved to a header file.

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
Changes since V1:
 * Rename cleanup() to waitpid_cleanup()
 * Kill child_1 pid in waitpid_cleanup()
 * Remove waitpid() calls from waitpid_cleanup()
 * Move mmap/unmap of fork_kid_pid to the setup
   and cleanup functions
 * Removed the 'fail = FAILED' logic
 * Created reap_children(). It calls waitpid() with necessary
   arguments and verifies that all the expected pids have
   terminated as they should

 testcases/kernel/syscalls/waitpid/waitpid06.c      |  313 +++-----------------
 testcases/kernel/syscalls/waitpid/waitpid_common.h |  145 +++++++++
 2 files changed, 183 insertions(+), 275 deletions(-)
 create mode 100644 testcases/kernel/syscalls/waitpid/waitpid_common.h

diff --git a/testcases/kernel/syscalls/waitpid/waitpid06.c b/testcases/kernel/syscalls/waitpid/waitpid06.c
index dbbc104..677835e 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid06.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid06.c
@@ -1,303 +1,66 @@
 /*
+ * Copyright (c) International Business Machines  Corp., 2001
  *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * This program is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
  *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * History
+ *	07/2001 John George
+ *		-Ported
+ *      04/2002 wjhuie sigset cleanups
  */
 
 /*
- * NAME
- *	waitpid06.c
- *
  * DESCRIPTION
- *	Tests to see if pid's returned from fork and waitpid are same.
+ *	Tests to see if pids returned from fork and waitpid are same.
  *
  * ALGORITHM
  *	Check proper functioning of waitpid with pid = -1 and arg = 0
- *
- * USAGE:  <for command-line>
- *      waitpid06 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- *      where,  -c n : Run n copies concurrently.
- *              -e   : Turn on errno logging.
- *              -i n : Execute test n times.
- *              -I x : Execute test for x seconds.
- *              -P x : Pause for x seconds between iterations.
- *              -t   : Turn on syscall timing.
- *
- * History
- *	07/2001 John George
- *		-Ported
- *      04/2002 wjhuie sigset cleanups
- *
- * Restrictions
- *	None
  */
 
-#include <sys/types.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include "test.h"
-
-static void setup_sigint(void);
-static void do_child_1(void);
-static void setup(void);
-static void cleanup(void);
-
-char *TCID = "waitpid06";
-int TST_TOTAL = 1;
-volatile int intintr;
-static void inthandlr();
-static void do_exit(void);
-static int flag;
-
-#define	FAILED	1
-#define	MAXKIDS	8
-
-#ifdef UCLINUX
-static char *argv0;
-static void do_child_2_uclinux(void);
-#endif
-
-int main(int argc, char **argv)
-{
-	int lc;
-	int fail = 0;
-	int pid;
-	int status;
-
-	tst_parse_opts(argc, argv, NULL, NULL);
-
-#ifdef UCLINUX
-	argv0 = argv[0];
-
-	maybe_run_child(&do_child_1, "n", 1);
-	maybe_run_child(&do_child_2_uclinux, "n", 2);
-#endif
-
-	setup();
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		pid = FORK_OR_VFORK();
-		if (pid < 0) {
-			tst_resm(TINFO, "Fork Failed, may be OK under stress");
-			exit(pid);
-		} else if (pid == 0) {
-			/*
-			 * Child:
-			 * Set up to catch SIGINT.  The kids will wait till a
-			 * SIGINT has been received before they proceed.
-			 */
-#ifdef UCLINUX
-			if (self_exec(argv[0], "n", 1) < 0) {
-				tst_resm(TINFO, "self_exec failed");
-				exit(pid);
-			}
-#else
-			do_child_1();
-#endif
-		} else {	/* parent */
-			fail = 0;
-			waitpid(pid, &status, 0);
-			if (WEXITSTATUS(status) != 0) {
-				tst_resm(TFAIL, "child returned bad status");
-				fail = 1;
-			}
-			if (fail)
-				tst_resm(TFAIL, "%s FAILED", TCID);
-			else
-				tst_resm(TPASS, "%s PASSED", TCID);
-		}
-	}
-
-	cleanup();
-	tst_exit();
-}
-
-/*
- * setup_sigint()
- *	Sets up a SIGINT handler
- */
-static void setup_sigint(void)
-{
-	if ((sig_t) signal(SIGINT, inthandlr) == SIG_ERR) {
-		tst_resm(TFAIL, "signal SIGINT failed. " "errno = %d", errno);
-		exit(-1);
-	}
-}
+#include "waitpid_common.h"
 
 static void do_child_1(void)
 {
-	int kid_count, fork_kid_pid[MAXKIDS];
-	int ret_val;
-	int i, j, k, found;
-	int group1, group2;
-	int wait_kid_pid[MAXKIDS], status;
-
-	setup_sigint();
-
-	group1 = getpgrp();
-	for (kid_count = 0; kid_count < MAXKIDS; kid_count++) {
-		if (kid_count == (MAXKIDS / 2))
-			group2 = setpgrp();
-
-		intintr = 0;
-		ret_val = FORK_OR_VFORK();
-		if (ret_val == 0) {	/* child */
-#ifdef UCLINUX
-			if (self_exec(argv0, "n", 2) < 0) {
-				tst_resm(TFAIL, "Fork kid %d failed. "
-					 "errno = %d", kid_count, errno);
-				exit(ret_val);
-			}
-#else
-			do_exit();
-#endif
-		} else if (ret_val < 0) {
-			tst_resm(TFAIL, "Fork kid %d failed. "
-				 "errno = %d", kid_count, errno);
-			exit(ret_val);
-		}
-
-		/* parent */
-		fork_kid_pid[kid_count] = ret_val;
-	}
+	pid_t pid;
+	int i;
 
-#ifdef UCLINUX
-	/* Give the kids a chance to setup SIGINT again, since this is
-	 * cleared by exec().
-	 */
-	sleep(3);
-#endif
-
-	/* Now send all the kids a SIGINT to tell them to
-	 * proceed
-	 */
 	for (i = 0; i < MAXKIDS; i++) {
-		if (kill(fork_kid_pid[i], SIGINT) < 0) {
-			tst_resm(TFAIL, "Kill of child %d "
-				 "failed, errno = %d", i, errno);
-			exit(-1);
-		}
-	}
+		if (i == (MAXKIDS / 2))
+			SAFE_SETPGID(0, 0);
 
-	/*
-	 * Wait till all kids have terminated.  Stash away their
-	 * pid's in an array.
-	 */
-	kid_count = 0;
-	errno = 0;
-	while (((ret_val = waitpid(-1, &status, 0)) != -1) || (errno == EINTR)) {
-		if (ret_val == -1)
-			continue;
+		pid = SAFE_FORK();
+		if (pid == 0)
+			do_exit(0);
 
-		if (!WIFEXITED(status)) {
-			tst_resm(TFAIL, "Child %d did not exit "
-				 "normally", ret_val);
-			flag = FAILED;
-			printf("status: %d\n", status);
-		} else {
-			if (WEXITSTATUS(status) != 3) {
-				tst_resm(TFAIL, "Child %d"
-					 "exited with wrong "
-					 "status", ret_val);
-				tst_resm(TFAIL, "Expected 3 "
-					 "got %d ", WEXITSTATUS(status));
-				flag = FAILED;
-			}
-		}
-		wait_kid_pid[kid_count++] = ret_val;
+		fork_kid_pid[i] = pid;
 	}
 
-	/*
-	 * Check that for every entry in the fork_kid_pid array,
-	 * there is a matching pid in the wait_kid_pid array. If
-	 * not, it's an error.
-	 */
-	for (i = 0; i < kid_count; i++) {
-		found = 0;
-		for (j = 0; j < MAXKIDS; j++) {
-			if (fork_kid_pid[j] == wait_kid_pid[i]) {
-				found = 1;
-				break;
-			}
-		}
+	TST_CHECKPOINT_WAKE2(0, MAXKIDS);
 
-		if (!found) {
-			tst_resm(TFAIL, "Did not find a "
-				 "wait_kid_pid for the "
-				 "fork_kid_pid of %d", wait_kid_pid[i]);
-			for (k = 0; k < MAXKIDS; k++) {
-				tst_resm(TFAIL,
-					 "fork_kid_pid[%d] = "
-					 "%d", k, fork_kid_pid[k]);
-			}
-			for (k = 0; k < kid_count; k++) {
-				tst_resm(TFAIL,
-					 "wait_kid_pid[%d] = "
-					 "%d", k, wait_kid_pid[k]);
-			}
-			flag = FAILED;
-		}
+	if (reap_children(-1, 0, fork_kid_pid, MAXKIDS)) {
+		tst_res(TFAIL, "reap_children() failed");
+		return;
 	}
 
-	if (flag)
-		exit(1);
-	else
-		exit(0);
-}
-
-#ifdef UCLINUX
-/*
- * do_child_2_uclinux()
- *	sets up sigint handler again, then calls the normal child 2 function
- */
-static void do_child_2_uclinux(void)
-{
-	setup_sigint();
-	do_exit();
-}
-#endif
-
-static void setup(void)
-{
-	TEST_PAUSE;
-}
-
-static void cleanup(void)
-{
+	tst_res(TPASS, "Test PASSED");
 }
 
-static void inthandlr(void)
-{
-	intintr++;
-}
-
-static void wait_for_parent(void)
-{
-	int testvar;
-
-	while (!intintr)
-		testvar = 0;
-}
-
-static void do_exit(void)
-{
-	wait_for_parent();
-	exit(3);
-}
+static struct tst_test test = {
+	.tid = "waitpid06",
+	.forks_child = 1,
+	.needs_checkpoints = 1,
+	.setup = waitpid_setup,
+	.cleanup = waitpid_cleanup,
+	.test_all = waitpid_test,
+};
diff --git a/testcases/kernel/syscalls/waitpid/waitpid_common.h b/testcases/kernel/syscalls/waitpid/waitpid_common.h
new file mode 100644
index 0000000..6ed5b19
--- /dev/null
+++ b/testcases/kernel/syscalls/waitpid/waitpid_common.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2016 Linux Test Project
+ *
+ * Licensed under the GNU GPLv2 or later.
+ * This program is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ */
+
+#ifndef WAITPID_COMMON_H__
+#define WAITPID_COMMON_H__
+
+#include <sys/types.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include "tst_test.h"
+
+#define	MAXKIDS	8
+
+static pid_t *fork_kid_pid;
+static pid_t child_1_pid;
+
+static void do_child_1(void);
+
+static void waitpid_setup(void)
+{
+	fork_kid_pid = SAFE_MMAP(NULL, sizeof(*fork_kid_pid) * MAXKIDS,
+				 PROT_READ | PROT_WRITE,
+				 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+}
+
+static void waitpid_cleanup(void)
+{
+	int i;
+
+	for (i = 0; i < MAXKIDS; i++) {
+		if (fork_kid_pid[i] > 0)
+			kill(fork_kid_pid[i], SIGKILL);
+	}
+
+	if (child_1_pid > 0)
+		kill(child_1_pid, SIGKILL);
+
+	munmap(fork_kid_pid, sizeof(*fork_kid_pid) * MAXKIDS);
+}
+
+static void waitpid_test(void)
+{
+	int status;
+
+	child_1_pid = SAFE_FORK();
+	if (child_1_pid == 0) {
+		do_child_1();
+	} else {
+		SAFE_WAITPID(child_1_pid, &status, 0);
+
+		child_1_pid = 0;
+
+		if (!WIFEXITED(status))
+			tst_brk(TBROK, "Child 1 exited abnormally");
+
+		if (WEXITSTATUS(status) != 0)
+			tst_res(TFAIL, "Child 1 returned bad status");
+	}
+}
+
+static void do_exit(int stop)
+{
+	TST_CHECKPOINT_WAIT(0);
+
+	if (stop)
+		kill(getpid(), SIGSTOP);
+
+	exit(3);
+}
+
+static int reap_children(pid_t wp_pid, int wp_opts, pid_t *children, int len)
+{
+	pid_t pid;
+	int i;
+	int status;
+
+	for (;;) {
+		pid = waitpid(wp_pid, &status, wp_opts);
+
+		if (pid == -1) {
+			if (errno == EINTR)
+				continue;
+
+			break;
+		}
+
+		if (pid == 0) {
+			if (wp_opts & WNOHANG)
+				continue;
+
+			tst_res(TFAIL, "waitpid() returned 0 unexpectedly");
+			return -1;
+		}
+
+		for (i = 0; i < len; i++) {
+			if (pid == children[i]) {
+				children[i] = 0;
+				break;
+			}
+		}
+
+		if (i == len) {
+			tst_res(TFAIL, "Pid %d not found", pid);
+			return -1;
+		}
+
+		if (!WIFEXITED(status)) {
+			tst_res(TFAIL, "Pid %d exited abnormally", pid);
+			return -1;
+		}
+
+		if (WEXITSTATUS(status) != 3) {
+			tst_res(TFAIL, "Pid %d exited with %d, expected 3",
+				pid, WEXITSTATUS(status));
+			return -1;
+		}
+	}
+
+	for (i = 0; i < len; i++) {
+		if (children[i]) {
+			tst_res(TFAIL, "Pid %d not reaped", children[i]);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+#endif /* WAITPID_COMMON_H__ */
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [LTP] [PATCH V2 2/4] waitpid07: use the new API
  2016-07-19 14:55     ` [LTP] [PATCH V2 1/4] " Stanislav Kholmanskikh
@ 2016-07-19 14:55       ` Stanislav Kholmanskikh
  2016-07-19 14:55         ` [LTP] [PATCH V2 3/4] waitpid08: " Stanislav Kholmanskikh
  2016-08-03 16:12         ` [LTP] [PATCH V2 2/4] waitpid07: " Cyril Hrubis
  2016-08-03 16:01       ` [LTP] [PATCH V2 1/4] waitpid06: " Cyril Hrubis
  1 sibling, 2 replies; 24+ messages in thread
From: Stanislav Kholmanskikh @ 2016-07-19 14:55 UTC (permalink / raw)
  To: ltp

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
Changes since V1:
 * Use waitpid_setup(), waitpid_cleanup()
 * Use reap_children()

testcases/kernel/syscalls/waitpid/waitpid07.c |  329 ++++---------------------
 1 files changed, 45 insertions(+), 284 deletions(-)

diff --git a/testcases/kernel/syscalls/waitpid/waitpid07.c b/testcases/kernel/syscalls/waitpid/waitpid07.c
index 92f921d..682d9e9 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid07.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid07.c
@@ -1,314 +1,75 @@
 /*
+ * Copyright (c) International Business Machines  Corp., 2001
  *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * This program is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
  *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * History
+ *	07/2001 John George
+ *		-Ported
+ *      04/2002 wjhuie sigset cleanups
  */
 
 /*
- * NAME
- *	waitpid07.c
- *
  * DESCRIPTION
- *	Tests to see if pid's returned from fork and waitpid are same.
+ *	Tests to see if pids returned from fork and waitpid are same.
  *
  * ALGORITHM
  *	Check proper functioning of waitpid with pid = -1 and arg = WNOHANG
- *
- * USAGE:  <for command-line>
- *      waitpid07 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- *      where,  -c n : Run n copies concurrently.
- *              -e   : Turn on errno logging.
- *              -i n : Execute test n times.
- *              -I x : Execute test for x seconds.
- *              -P x : Pause for x seconds between iterations.
- *              -t   : Turn on syscall timing.
- *
- * History
- *	07/2001 John George
- *		-Ported
- *      04/2002 wjhuie sigset cleanups
- *
- * Restrictions
- *	None
  */
 
-#include <sys/types.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include "test.h"
-
-static void setup_sigint(void);
-static void do_child_1(void);
-static void setup(void);
-static void cleanup(void);
-
-char *TCID = "waitpid07";
-int TST_TOTAL = 1;
-
-volatile int intintr;
-static int flag;
-static void inthandlr();
-static void do_exit(void);
-
-#define	FAILED	1
-#define MAXKIDS	8
-
-#ifdef UCLINUX
-static char *argv0;
-static void do_child_2_uclinux(void);
-#endif
-
-int main(int argc, char **argv)
-{
-	int lc;
-
-	int status;
-	int fail = 0;
-	int pid;
-
-	tst_parse_opts(argc, argv, NULL, NULL);
-
-#ifdef UCLINUX
-	argv0 = argv[0];
-
-	maybe_run_child(&do_child_1, "n", 1);
-	maybe_run_child(&do_child_2_uclinux, "n", 2);
-#endif
-
-	setup();
-
-	/* check for looping state if -i option is given */
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-
-		pid = FORK_OR_VFORK();
-		if (pid < 0) {
-			tst_resm(TFAIL, "Fork Failed, may be OK under stress");
-		} else if (pid == 0) {
-
-			/*
-			 * Child:
-			 * Set up to catch SIGINT.  The kids will wait till a
-			 * SIGINT has been received before they proceed.
-			 */
-#ifdef UCLINUX
-			if (self_exec(argv[0], "n", 1) < 0) {
-				tst_resm(TINFO, "self_exec failed");
-				exit(pid);
-			}
-#else
-			do_child_1();
-#endif
-		} else {
-			fail = 0;
-			waitpid(pid, &status, 0);
-			if (WEXITSTATUS(status) != 0) {
-				tst_resm(TFAIL, "child returned bad status");
-				fail = 1;
-			}
-			if (fail)
-				tst_resm(TFAIL, "%s FAILED", TCID);
-			else
-				tst_resm(TPASS, "%s PASSED", TCID);
-		}
-	}
-
-	cleanup();
-	tst_exit();
-}
-
-/*
- * setup_sigint()
- *	Sets up a SIGINT handler
- */
-static void setup_sigint(void)
-{
-	if ((sig_t) signal(SIGINT, inthandlr) == SIG_ERR) {
-		tst_resm(TFAIL, "signal SIGINT failed. " "errno = %d", errno);
-		exit(-1);
-	}
-}
+#include "waitpid_common.h"
 
 static void do_child_1(void)
 {
-	int kid_count, fork_kid_pid[MAXKIDS];
-	int ret_val;
-	int i, j, k, found;
-	int group1, group2;
-	int wait_kid_pid[MAXKIDS], status;
-
-	setup_sigint();
-
-	group1 = getpgrp();
-
-	for (kid_count = 0; kid_count < MAXKIDS; kid_count++) {
-		if (kid_count == (MAXKIDS / 2))
-			group2 = setpgrp();
+	pid_t pid;
+	int i;
+	int status;
 
-		intintr = 0;
-		ret_val = FORK_OR_VFORK();
-		if (ret_val == 0) {
-#ifdef UCLINUX
-			if (self_exec(argv0, "n", 2) < 0) {
-				tst_resm(TFAIL, "Fork kid %d failed. "
-					 "errno = %d", kid_count, errno);
-				exit(ret_val);
-			}
-#else
-			do_exit();
-#endif
-		}
+	for (i = 0; i < MAXKIDS; i++) {
+		if (i == (MAXKIDS / 2))
+			SAFE_SETPGID(0, 0);
 
-		if (ret_val < 0) {
-			tst_brkm(TFAIL, NULL, "Fork kid %d failed. "
-				 "errno = %d", kid_count, errno);
-		}
+		pid = SAFE_FORK();
+		if (pid == 0)
+			do_exit(0);
 
-		/* parent */
-		fork_kid_pid[kid_count] = ret_val;
+		fork_kid_pid[i] = pid;
 	}
 
 	/* Check that waitpid with WNOHANG returns zero */
-	ret_val = waitpid(-1, &status, WNOHANG);
-	if (ret_val != 0) {
-		tst_resm(TFAIL, "Waitpid returned wrong value");
-		tst_resm(TFAIL, "Expected 0 got %d", ret_val);
-		flag = FAILED;
+	pid = waitpid(-1, &status, WNOHANG);
+	if (pid != 0) {
+		tst_res(TFAIL, "waitpid() returned %d, expected 0",
+			pid);
+		return;
 	}
-#ifdef UCLINUX
-	/* Give the kids a chance to setup SIGINT again, since this is
-	 * cleared by exec().
-	 */
-	sleep(3);
-#endif
 
-	/* Now send all the kids a SIGINT to tell them to
-	 * proceed
-	 */
-	for (i = 0; i < MAXKIDS; i++) {
-		if (kill(fork_kid_pid[i], SIGINT) < 0) {
-			tst_brkm(TFAIL, NULL, "Kill of child %d "
-				 "failed, errno = %d", i, errno);
-		}
-	}
-
-	/*
-	 * Wait till all kids have terminated.  Stash away their
-	 * pid's in an array.
-	 */
-	kid_count = 0;
-	errno = 0;
-	while (((ret_val = waitpid(-1, &status, WNOHANG)) != -1)
-	       || (errno == EINTR)) {
-		if ((ret_val == -1) || (ret_val == 0))
-			continue;
-
-		if (!WIFEXITED(status)) {
-			tst_resm(TFAIL, "Child %d did not exit "
-				 "normally", ret_val);
-			flag = FAILED;
-		} else {
-			if (WEXITSTATUS(status) != 3) {
-				tst_resm(TFAIL, "Child %d "
-					 "exited with wrong "
-					 "status", ret_val);
-				tst_resm(TFAIL, "Expected 3 "
-					 "got %d ", WEXITSTATUS(status));
-				flag = FAILED;
-			}
-		}
-		wait_kid_pid[kid_count++] = ret_val;
-	}
+	TST_CHECKPOINT_WAKE2(0, MAXKIDS);
 
-	/*
-	 * Check that for every entry in the fork_kid_pid array,
-	 * there is a matching pid in the wait_kid_pid array. If
-	 * not, it's an error.
-	 */
-	for (i = 0; i < kid_count; i++) {
-		found = 0;
-		for (j = 0; j < MAXKIDS; j++) {
-			if (fork_kid_pid[j] == wait_kid_pid[i]) {
-				found = 1;
-				break;
-			}
-		}
-
-		if (!found) {
-			tst_resm(TFAIL, "Did not find a "
-				 "wait_kid_pid for the "
-				 "fork_kid_pid of %d", wait_kid_pid[i]);
-			for (k = 0; k < MAXKIDS; k++) {
-				tst_resm(TFAIL,
-					 "fork_kid_pid[%d] = "
-					 "%d", k, fork_kid_pid[k]);
-			}
-			for (k = 0; k < kid_count; k++) {
-				tst_resm(TFAIL,
-					 "wait_kid_pid[%d] = "
-					 "%d", k, wait_kid_pid[k]);
-			}
-			flag = FAILED;
-		}
+	if (reap_children(-1, WNOHANG, fork_kid_pid, MAXKIDS)) {
+		tst_res(TFAIL, "reap_children() failed");
+		return;
 	}
 
-	if (flag)
-		exit(1);
-	else
-		exit(0);
-}
-
-#ifdef UCLINUX
-/*
- * do_child_2_uclinux()
- *	sets up sigint handler again, then calls the normal child 2 function
- */
-static void do_child_2_uclinux(void)
-{
-	setup_sigint();
-	do_exit();
-}
-#endif
-
-static void setup(void)
-{
-	TEST_PAUSE;
+	tst_res(TPASS, "Test PASSED");
 }
 
-static void cleanup(void)
-{
-}
-
-static void inthandlr(void)
-{
-	intintr++;
-}
-
-static void wait_for_parent(void)
-{
-	int testvar;
-
-	while (!intintr)
-		testvar = 0;
-}
-
-static void do_exit(void)
-{
-	wait_for_parent();
-	exit(3);
-}
+static struct tst_test test = {
+	.tid = "waitpid07",
+	.forks_child = 1,
+	.needs_checkpoints = 1,
+	.setup = waitpid_setup,
+	.cleanup = waitpid_cleanup,
+	.test_all = waitpid_test,
+};
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [LTP] [PATCH V2 3/4] waitpid08: use the new API
  2016-07-19 14:55       ` [LTP] [PATCH V2 2/4] waitpid07: " Stanislav Kholmanskikh
@ 2016-07-19 14:55         ` Stanislav Kholmanskikh
  2016-07-19 14:55           ` [LTP] [PATCH V2 4/4] waitpid11: " Stanislav Kholmanskikh
  2016-08-03 16:12         ` [LTP] [PATCH V2 2/4] waitpid07: " Cyril Hrubis
  1 sibling, 1 reply; 24+ messages in thread
From: Stanislav Kholmanskikh @ 2016-07-19 14:55 UTC (permalink / raw)
  To: ltp

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
Changes since V1:
 * Use waitpid_setup(), waitpid_cleanup()
 * Use reap_children()
 * Use tst_strerrno

 testcases/kernel/syscalls/waitpid/waitpid08.c |  353 ++++---------------------
 1 files changed, 54 insertions(+), 299 deletions(-)

diff --git a/testcases/kernel/syscalls/waitpid/waitpid08.c b/testcases/kernel/syscalls/waitpid/waitpid08.c
index b2e9e9b..0249e68 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid08.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid08.c
@@ -1,341 +1,96 @@
 /*
+ * Copyright (c) International Business Machines  Corp., 2001
  *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * This program is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
  *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * History
+ *	07/2001 John George
+ *		-Ported
+ *      04/2002 wjhuie sigset cleanups
  */
 
 /*
- * NAME
- *	waitpid08.c
- *
  * DESCRIPTION
- *	Tests to see if pid's returned from fork and waitpid are same
+ *	Tests to see if pids returned from fork and waitpid are same.
  *
  * ALGORITHM
  *	Check proper functioning of waitpid with pid = -1 and arg =
  *	WUNTRACED
- *
- * USAGE:  <for command-line>
- *      waitpid08 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- *      where,  -c n : Run n copies concurrently.
- *              -e   : Turn on errno logging.
- *              -i n : Execute test n times.
- *              -I x : Execute test for x seconds.
- *              -P x : Pause for x seconds between iterations.
- *              -t   : Turn on syscall timing.
- *
- * History
- *	07/2001 John George
- *		-Ported
- *      04/2002 wjhuie sigset cleanups
- *
- * Restrictions
- *	None
  */
 
-#include <sys/types.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include "test.h"
-
-static void inthandlr();
-static void do_exit(void);
-static void setup_sigint(void);
-static void do_child_1(void);
-static void setup(void);
-static void cleanup(void);
-
-char *TCID = "waitpid08";
-int TST_TOTAL = 1;
-volatile int intintr;
-static int fail;
-
-#define	MAXKIDS	8
-
-#ifdef UCLINUX
-static char *argv0;
-static void do_child_2_uclinux(void);
-#endif
-
-int main(int argc, char **argv)
-{
-	int lc;
-
-	int status;
-	int pid;
-
-	tst_parse_opts(argc, argv, NULL, NULL);
-
-#ifdef UCLINUX
-	argv0 = argv[0];
-
-	maybe_run_child(&do_child_1, "n", 1);
-	maybe_run_child(&do_child_2_uclinux, "n", 2);
-#endif
-
-	setup();
-
-	/* check for looping state if -i option is given */
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		/* reset tst_count in case we are looping */
-		tst_count = 0;
-		fail = 0;
-
-		pid = FORK_OR_VFORK();
-		if (pid < 0) {
-			tst_resm(TFAIL, "Fork Failed, may be OK under stress");
-
-		} else if (pid == 0) {
-			/*
-			 * Child:
-			 * Set up to catch SIGINT.
-			 * The kids will wait till a SIGINT has been received
-			 * before they proceed.
-			 */
-#ifdef UCLINUX
-			if (self_exec(argv[0], "n", 1) < 0) {
-				tst_resm(TINFO, "self_exec failed");
-				exit(pid);
-			}
-#else
-			do_child_1();
-#endif
-		} else {	/* parent */
-			waitpid(pid, &status, 0);
-			if (WEXITSTATUS(status) != 0) {
-				tst_resm(TFAIL, "child returned bad status");
-				fail = 1;
-			}
-			if (fail)
-				tst_resm(TFAIL, "%s FAILED", TCID);
-			else
-				tst_resm(TPASS, "%s PASSED", TCID);
-		}
-	}
-
-	cleanup();
-	tst_exit();
-}
-
-/*
- * setup_sigint()
- *	Sets up a SIGINT handler
- */
-static void setup_sigint(void)
-{
-	if ((sig_t) signal(SIGINT, inthandlr) == SIG_ERR) {
-		tst_resm(TFAIL, "signal SIGINT failed. " "errno = %d", errno);
-		exit(-1);
-	}
-}
+#include "waitpid_common.h"
 
 static void do_child_1(void)
 {
-	int kid_count, fork_kid_pid[MAXKIDS];
-	int ret_val;
-	int i, j, k, found;
-	int group1, group2;
-	int wait_kid_pid[MAXKIDS], status;
-
-	setup_sigint();
-
-	group1 = getpgrp();
-
-	for (kid_count = 0; kid_count < MAXKIDS; kid_count++) {
-		if (kid_count == (MAXKIDS / 2))
-			group2 = setpgrp();
+	pid_t pid;
+	int i;
+	int status;
 
-		intintr = 0;
-		ret_val = FORK_OR_VFORK();
-		if (ret_val == 0) {
-#ifdef UCLINUX
-			if (self_exec(argv0, "n", 2) < 0) {
-				tst_resm(TFAIL, "Fork kid %d failed. "
-					 "errno = %d", kid_count, errno);
-				exit(ret_val);
-			}
-#else
-			do_exit();
-#endif
-		}
+	for (i = 0; i < MAXKIDS; i++) {
+		if (i == (MAXKIDS / 2))
+			SAFE_SETPGID(0, 0);
 
-		if (ret_val < 0) {
-			tst_resm(TFAIL, "Fork kid %d failed. "
-				 "errno = %d", kid_count, errno);
-			exit(ret_val);
-		}
+		pid = SAFE_FORK();
+		if (pid == 0)
+			do_exit(0);
 
-		/* parent */
-		fork_kid_pid[kid_count] = ret_val;
+		fork_kid_pid[i] = pid;
 	}
 
 	/* Check that waitpid with WNOHANG|WUNTRACED returns
 	 * zero
 	 */
-	ret_val = waitpid(-1, &status, WNOHANG | WUNTRACED);
-	if (ret_val != 0) {
-		tst_resm(TFAIL, "Waitpid returned wrong value");
-		tst_resm(TFAIL, "Expected 0 got %d", ret_val);
-		fail = 1;
-	}
-#ifdef UCLINUX
-	/* Give the kids a chance to setup SIGINT again, since this is
-	 * cleared by exec().
-	 */
-	sleep(3);
-#endif
-
-	/* Now send all the kids a SIGINT to tell them to
-	 * proceed
-	 */
-	for (i = 0; i < MAXKIDS; i++) {
-		if (kill(fork_kid_pid[i], SIGINT) < 0) {
-			tst_brkm(TFAIL, NULL, "Kill of child %d "
-				 "failed, errno = %d", i, errno);
-		}
+	pid = waitpid(-1, &status, WNOHANG | WUNTRACED);
+	if (pid != 0) {
+		tst_res(TFAIL,
+			"waitpid(WNOHANG | WUNTRACED) returned %d, expected 0",
+			pid);
+		return;
 	}
 
-	/*
-	 * Wait till all kids have terminated.  Stash away their
-	 * pid's in an array.
-	 */
-	kid_count = 0;
-	errno = 0;
-	while (((ret_val = waitpid(-1, &status, WUNTRACED)) !=
-		-1) || (errno == EINTR)) {
-		if (ret_val == -1)
-			continue;
+	TST_CHECKPOINT_WAKE2(0, MAXKIDS);
 
-		if (!WIFEXITED(status)) {
-			if (!WIFSTOPPED(status)) {
-				tst_resm(TFAIL, "Child %d did "
-					 "not stopped", ret_val);
-				fail = 1;
-			} else {
-				if (WSTOPSIG(status) != SIGSTOP) {
-					tst_resm(TFAIL,
-						 "Child %d "
-						 "exited with "
-						 "wrong status", ret_val);
-					tst_resm(TFAIL,
-						 "Expected "
-						 "SIGSTOP got %d",
-						 WSTOPSIG(status));
-					fail = 1;
-				}
-			}
-			if (kill(ret_val, SIGCONT) < 0) {
-				tst_resm(TFAIL, "Kill of child "
-					 "%d failed, errno = %d",
-					 ret_val, errno);
-				fail = 1;
-			}
-		}
-		wait_kid_pid[kid_count++] = ret_val;
-	}
-
-	/*
-	 * Check that for every entry in the fork_kid_pid array,
-	 * there is a matching pid in the wait_kid_pid array. If
-	 * not, it's an error.
-	 */
-	for (i = 0; i < kid_count; i++) {
-		found = 0;
-		for (j = 0; j < MAXKIDS; j++) {
-			if (fork_kid_pid[j] == wait_kid_pid[i]) {
-				found = 1;
-				break;
-			}
-		}
-		if (!found) {
-			tst_resm(TFAIL,
-				 "Did not find a wait_kid_pid "
-				 "for the fork_kid_pid of %d", wait_kid_pid[i]);
-			for (k = 0; k < MAXKIDS; k++) {
-				tst_resm(TFAIL,
-					 "fork_kid_pid[%d] = "
-					 "%d", k, fork_kid_pid[k]);
-			}
-			for (k = 0; k < kid_count; k++) {
-				tst_resm(TFAIL,
-					 "wait_kid_pid[%d] = "
-					 "%d", k, wait_kid_pid[k]);
-			}
-			fail = 1;
-		}
+	if (reap_children(-1, WUNTRACED, fork_kid_pid, MAXKIDS)) {
+		tst_res(TFAIL, "reap_children() failed");
+		return;
 	}
 
 	/*
 	 * Check that waitpid(WUNTRACED) returns -1 when no
 	 * stopped children
 	 */
-	ret_val = waitpid(-1, &status, WUNTRACED);
-	if (ret_val != -1) {
-		tst_resm(TFAIL, "Waitpid returned wrong value.");
-		tst_resm(TFAIL, "Expected -1 got %d from "
-			 "waitpid(WUNTRACED)", ret_val);
-		fail = 1;
+	pid = waitpid(-1, &status, WUNTRACED);
+	if (pid != -1) {
+		tst_res(TFAIL, "waitpid(WUNTRACED) returned %d, expected -1",
+			pid);
+		return;
 	}
 
 	if (errno != ECHILD) {
-		tst_resm(TFAIL, "Waitpid returned wrong errno.");
-		tst_resm(TFAIL, "Expected ECHILD got %d", errno);
-		fail = 1;
+		tst_res(TFAIL, "waitpid(WUNTRACED) set errno %s, expected %s",
+			tst_strerrno(errno), tst_strerrno(ECHILD));
+		return;
 	}
 
-	exit(fail);
-}
-
-#ifdef UCLINUX
-/*
- * do_child_2_uclinux()
- *	sets up sigint handler again, then calls the normal child 2 function
- */
-static void do_child_2_uclinux(void)
-{
-	setup_sigint();
-	do_exit();
-}
-#endif
-
-static void setup(void)
-{
-	TEST_PAUSE;
-}
-
-static void cleanup(void)
-{
+	tst_res(TPASS, "Test PASSED");
 }
 
-static void inthandlr(void)
-{
-	intintr++;
-}
-
-static void wait_for_parent(void)
-{
-	int testvar;
-
-	while (!intintr)
-		testvar = 0;
-}
-
-static void do_exit(void)
-{
-	wait_for_parent();
-	exit(3);
-}
+static struct tst_test test = {
+	.tid = "waitpid08",
+	.forks_child = 1,
+	.needs_checkpoints = 1,
+	.setup = waitpid_setup,
+	.cleanup = waitpid_cleanup,
+	.test_all = waitpid_test,
+};
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [LTP] [PATCH V2 4/4] waitpid11: use the new API
  2016-07-19 14:55         ` [LTP] [PATCH V2 3/4] waitpid08: " Stanislav Kholmanskikh
@ 2016-07-19 14:55           ` Stanislav Kholmanskikh
  0 siblings, 0 replies; 24+ messages in thread
From: Stanislav Kholmanskikh @ 2016-07-19 14:55 UTC (permalink / raw)
  To: ltp

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
Changes since V1:
 * Use waitpid_setup(), waitpid_cleanup()
 * Use reap_children()

 testcases/kernel/syscalls/waitpid/waitpid11.c |  342 ++++---------------------
 1 files changed, 45 insertions(+), 297 deletions(-)

diff --git a/testcases/kernel/syscalls/waitpid/waitpid11.c b/testcases/kernel/syscalls/waitpid/waitpid11.c
index 135ec56..3750823 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid11.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid11.c
@@ -1,327 +1,75 @@
 /*
+ * Copyright (c) International Business Machines  Corp., 2001
  *
- *   Copyright (c) International Business Machines  Corp., 2001
+ * This program is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
  *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * History
+ *	07/2001 John George
+ *		-Ported
+ *      04/2002 wjhuie sigset cleanups
  */
 
 /*
- * NAME
- *	waitpid11.c
- *
  * DESCRIPTION
- *	Tests to see if pid's returned from fork and waitpid are same
+ *	Tests to see if pids returned from fork and waitpid are same
  *
  * ALGORITHM
  * 	Check proper functioning of waitpid with pid = -1 and arg = 0
- *
- * USAGE:  <for command-line>
- *      waitpid11 [-c n] [-t]
- *      where,  -c n : Run n copies concurrently.
- *              -t   : Turn on syscall timing.
- *
- * History
- *	07/2001 John George
- *		-Ported
- *      04/2002 wjhuie sigset cleanups
- *
- * Restrictions
- *	None
  */
 
-#include <sys/types.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include "test.h"
-
-#define	MAXKIDS	8
-
-char *TCID = "waitpid11";
-int TST_TOTAL = 1;
-
-volatile int intintr;
-static void setup(void);
-static void cleanup(void);
-static void inthandlr();
-static void wait_for_parent(void);
-static void do_exit(void);
-static void setup_sigint(void);
-#ifdef UCLINUX
-static void do_exit_uclinux(void);
-#endif
-
-static int fail;
-static int fork_kid_pid[MAXKIDS];
+#include "waitpid_common.h"
 
-int main(int ac, char **av)
+static void do_child_1(void)
 {
-	int kid_count, ret_val, status;
-	int i, j, k, found;
-	int group1, group2;
-	int wait_kid_pid[MAXKIDS];
-	int pid;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-#ifdef UCLINUX
-	maybe_run_child(&do_exit_uclinux, "");
-#endif
-
-	setup();
-
-	tst_count = 0;
-	fail = 0;
-
-	/*
-	 * Need to have test run from child as test driver causes
-	 * test to be a session leader and setpgrp fails.
-	 */
-
-	pid = FORK_OR_VFORK();
-	if (pid > 0) {
-		waitpid(pid, &status, 0);
-		if (WEXITSTATUS(status) != 0) {
-			tst_resm(TFAIL, "child returned bad status");
-			fail = 1;
-		}
-		if (fail)
-			tst_resm(TFAIL, "%s FAILED", TCID);
-		else
-			tst_resm(TPASS, "%s PASSED", TCID);
-		tst_exit();
-	} else if (pid < 0)
-		tst_brkm(TBROK, cleanup, "fork failed");
-
-	/*
-	 * Set up to catch SIGINT.  The kids will wait till a SIGINT
-	 * has been received before they proceed.
-	 */
-	setup_sigint();
-
-	group1 = getpgrp();
-
-	for (kid_count = 0; kid_count < MAXKIDS; kid_count++) {
-		if (kid_count == (MAXKIDS / 2))
-			group2 = setpgrp();
-
-		intintr = 0;
-		ret_val = FORK_OR_VFORK();
-		if (ret_val == 0) {
-#ifdef UCLINUX
-			if (self_exec(av[0], "") < 0)
-				tst_resm(TFAIL | TERRNO, "self_exec kid %d "
-					 "failed", kid_count);
-#else
-			do_exit();
-#endif
-		}
-
-		if (ret_val < 0)
-			tst_brkm(TBROK|TERRNO, cleanup, "Fork kid %d failed",
-				 kid_count);
-
-		/* parent */
-		fork_kid_pid[kid_count] = ret_val;
-	}
+	pid_t pid, group;
+	int i;
 
-#ifdef UCLINUX
-	/* Give the kids a chance to setup SIGINT again, since this is
-	 * cleared by exec().
-	 */
-	sleep(3);
-#endif
+	group = SAFE_GETPGID(0);
 
-	/* Now send all the kids a SIGINT to tell them to proceed */
-	for (i = 0; i < MAXKIDS; i++)
-		if (kill(fork_kid_pid[i], SIGINT) < 0)
-			tst_resm(TFAIL | TERRNO, "Kill of child %d failed", i);
+	for (i = 0; i < MAXKIDS; i++) {
+		if (i == (MAXKIDS / 2))
+			SAFE_SETPGID(0, 0);
 
-	/*
-	 * Wait till all kids have terminated.  Stash away their
-	 * pid's in an array.
-	 */
-	kid_count = 0;
-	errno = 0;
-	while (((ret_val = waitpid(0, &status, 0)) != -1) || (errno == EINTR)) {
-		if (ret_val == -1)
-			continue;
+		pid = SAFE_FORK();
+		if (pid == 0)
+			do_exit(0);
 
-		if (!WIFEXITED(status)) {
-			tst_resm(TFAIL, "Child %d did not exit "
-				 "normally", ret_val);
-			fail = 1;
-		} else {
-			if (WEXITSTATUS(status) != 3) {
-				tst_resm(TFAIL, "Child %d exited with "
-					 "wrong status", ret_val);
-				tst_resm(TFAIL, "Expected 3 got %d",
-					 WEXITSTATUS(status));
-				fail = 1;
-			}
-		}
-		wait_kid_pid[kid_count++] = ret_val;
+		fork_kid_pid[i] = pid;
 	}
 
-	/*
-	 * Check that for every entry in the fork_kid_pid array,
-	 * there is a matching pid in the wait_kid_pid array.  If
-	 * not, it's an error.
-	 */
-	for (i = 0; i < kid_count; i++) {
-		found = 0;
-		for (j = (MAXKIDS / 2); j < MAXKIDS; j++) {
-			if (fork_kid_pid[j] == wait_kid_pid[i]) {
-				found = 1;
-				break;
-			}
-		}
-		if (!found) {
-			tst_resm(TFAIL, "Did not find a fork_kid_pid "
-				 "for the wait_kid_pid of %d", wait_kid_pid[i]);
-			for (k = 0; k < MAXKIDS; k++) {
-				tst_resm(TFAIL, "fork_kid_pid[%d] = "
-					 "%d", k, fork_kid_pid[k]);
-			}
-			for (k = 0; k < kid_count; k++) {
-				tst_resm(TFAIL, "wait_kid_pid[%d] = "
-					 "%d", k, wait_kid_pid[k]);
-			}
-			fail = 1;
-		}
-	}
+	TST_CHECKPOINT_WAKE2(0, MAXKIDS);
 
-	if (kid_count != (MAXKIDS / 2)) {
-		tst_resm(TFAIL, "Wrong number of children waited on "
-			 "for pid = 0");
-		tst_resm(TFAIL, "Expected 4 got %d", kid_count);
-		fail = 1;
+	if (reap_children(0, 0, fork_kid_pid + (MAXKIDS / 2), MAXKIDS / 2)) {
+		tst_res(TFAIL, "reap_children(0) failed");
+		return;
 	}
 
 	/* Make sure can pickup children in a diff. process group */
-
-	kid_count = 0;
-	errno = 0;
-	while (((ret_val = waitpid(-(group1), &status, 0)) != -1) ||
-	       (errno == EINTR)) {
-		if (ret_val == -1)
-			continue;
-		if (!WIFEXITED(status)) {
-			tst_resm(TFAIL, "Child %d did not exit "
-				 "normally", ret_val);
-			fail = 1;
-		} else {
-			if (WEXITSTATUS(status) != 3) {
-				tst_resm(TFAIL, "Child %d exited with "
-					 "wrong status", ret_val);
-				tst_resm(TFAIL, "Expected 3 got %d",
-					 WEXITSTATUS(status));
-				fail = 1;
-			}
-		}
-		wait_kid_pid[kid_count++] = ret_val;
-	}
-
-	/*
-	 * Check that for every entry in the fork_kid_pid array,
-	 * there is a matching pid in the wait_kid_pid array.  If
-	 * not, it's an error.
-	 */
-	for (i = 0; i < kid_count; i++) {
-		found = 0;
-		for (j = 0; j < (MAXKIDS / 2); j++) {
-			if (fork_kid_pid[j] == wait_kid_pid[i]) {
-				found = 1;
-				break;
-			}
-		}
-		if (!found) {
-			tst_resm(TFAIL, "Did not find a fork_kid_pid "
-				 "for the wait_kid_pid of %d", wait_kid_pid[i]);
-			for (k = 0; k < MAXKIDS; k++)
-				tst_resm(TFAIL, "fork_kid_pid[%d] = "
-					 "%d", k, fork_kid_pid[k]);
-			for (k = 0; k < kid_count; k++)
-				tst_resm(TFAIL, "wait_kid_pid[%d] = "
-					 "%d", k, wait_kid_pid[k]);
-			fail = 1;
-		}
-	}
-
-	memset(fork_kid_pid, 0, sizeof(fork_kid_pid));
-
-	if (kid_count != (MAXKIDS / 2)) {
-		tst_resm(TFAIL, "Wrong number of children waited on "
-			 "for pid = 0");
-		tst_resm(TFAIL, "Expected 4 got %d", kid_count);
-		fail = 1;
-	}
-
-	if (fail)
-		tst_resm(TFAIL, "Test FAILED");
-	else
-		tst_resm(TPASS, "Test PASSED");
-
-	cleanup();
-	tst_exit();
-}
-
-static void setup_sigint(void)
-{
-	if (signal(SIGINT, inthandlr) == SIG_ERR)
-		tst_brkm(TFAIL | TERRNO, NULL, "signal SIGINT failed");
-}
-
-static void setup(void)
-{
-	TEST_PAUSE;
-}
-
-static void cleanup(void)
-{
-	int i;
-
-	for (i = 0; i < MAXKIDS; i++) {
-		if (fork_kid_pid[i] > 0)
-			kill(fork_kid_pid[i], SIGKILL);
+	if (reap_children(-group, 0, fork_kid_pid, MAXKIDS / 2)) {
+		tst_res(TFAIL, "reap_children(%d) failed",
+			-group);
+		return;
 	}
-}
-
-static void inthandlr(void)
-{
-	intintr++;
-}
-
-static void wait_for_parent(void)
-{
-	int testvar;
-
-	while (!intintr)
-		testvar = 0;
-}
 
-static void do_exit(void)
-{
-	wait_for_parent();
-	exit(3);
+	tst_res(TPASS, "Test PASSED");
 }
 
-#ifdef UCLINUX
-static void do_exit_uclinux(void)
-{
-	setup_sigint();
-	do_exit();
-}
-#endif
+static struct tst_test test = {
+	.tid = "waitpid11",
+	.forks_child = 1,
+	.needs_checkpoints = 1,
+	.setup = waitpid_setup,
+	.cleanup = waitpid_cleanup,
+	.test_all = waitpid_test,
+};
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [LTP] [PATCH V2 4/8] waitpid09: use the new API
  2016-07-19 12:41       ` Cyril Hrubis
@ 2016-07-19 14:57         ` Stanislav Kholmanskikh
  0 siblings, 0 replies; 24+ messages in thread
From: Stanislav Kholmanskikh @ 2016-07-19 14:57 UTC (permalink / raw)
  To: ltp



On 07/19/2016 03:41 PM, Cyril Hrubis wrote:
> Hi!
>> This patch addresses all your comments, except the one about do_exit(),
>> because do_exit() is required for case 0.
>
> What I meant was to move the two lines that are in do_exit() to the if
> in the case0(). Previously the function was called from two places (one
> was the uclinux maybe_run_child and another one was after the fork) but
> now it does not make any sense to keep it as a separate function if it's
> called only from one place in the code.
>
> Or is there another reason to keep it in a fucntion I don't see?

No, there is no such reason.

I didn't get what you meant at that time, but now it's clear for me. 
Will update the patch.

>
>> +static void case2(void)
>>   {
>> +	pid_t ret;
>> +	int status;
>> +
>> +	ret = waitpid(-1, &status, 0);
>> +
>> +	if (ret != -1) {
>> +		tst_res(TFAIL, "Expected -1 got %d", ret);
>> +		return;
>> +	}
>> +	if (errno != ECHILD) {
>> +		tst_res(TFAIL, "Expected ECHILD got %d",
>> +			 errno);
>                          ^
> 			You should print the human-readable string
> 			returned by tst_strerrno() here as well or
> 			use TERRNO to have it printed by the library.
>

Okay.

>> +		return;
>> +	}
>> +
>> +	tst_res(TPASS, "Case 2 PASSED");
>>   }
>>
>> -static void inthandlr(void)
>> +static void case3(void)
>>   {
>> -	intintr++;
>> +	pid_t ret;
>> +	int status;
>> +
>> +	ret = waitpid(-1, &status, WNOHANG);
>> +	if (ret != -1) {
>> +		tst_res(TFAIL, "WNOHANG: Expected -1 got %d",
>> +			 ret);
>> +		return;
>> +	}
>> +	if (errno != ECHILD) {
>> +		tst_res(TFAIL, "WNOHANG: Expected ECHILD got "
>> +			 "%d", errno);
>
>                          Here as well.
>
>> +		return;
>> +	}
>> +
>> +	tst_res(TPASS, "Case 3 PASSED");
>>   }
>>
>> -static void wait_for_parent(void)
>
> Otherwise it looks good. Acked with the minor changes fixed.
>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 2/8] waitpid06: use the new API
  2016-07-18 13:05   ` Cyril Hrubis
  2016-07-19 14:55     ` [LTP] [PATCH V2 1/4] " Stanislav Kholmanskikh
@ 2016-08-03 10:19     ` Stanislav Kholmanskikh
  2016-08-03 12:01       ` Cyril Hrubis
  1 sibling, 1 reply; 24+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-03 10:19 UTC (permalink / raw)
  To: ltp

Hi, Cyril!

Did you get a chance to look at V2 series:

http://lists.linux.it/pipermail/ltp/2016-July/002235.html

?

Thanks.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH 2/8] waitpid06: use the new API
  2016-08-03 10:19     ` [LTP] [PATCH 2/8] " Stanislav Kholmanskikh
@ 2016-08-03 12:01       ` Cyril Hrubis
  0 siblings, 0 replies; 24+ messages in thread
From: Cyril Hrubis @ 2016-08-03 12:01 UTC (permalink / raw)
  To: ltp

Hi!
> Did you get a chance to look at V2 series:

Sorry that it takes too long, I have it on my TODO, hopefully will get
to it today.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH V2 1/4] waitpid06: use the new API
  2016-07-19 14:55     ` [LTP] [PATCH V2 1/4] " Stanislav Kholmanskikh
  2016-07-19 14:55       ` [LTP] [PATCH V2 2/4] waitpid07: " Stanislav Kholmanskikh
@ 2016-08-03 16:01       ` Cyril Hrubis
  1 sibling, 0 replies; 24+ messages in thread
From: Cyril Hrubis @ 2016-08-03 16:01 UTC (permalink / raw)
  To: ltp

Hi!
This version looks very good, a few minor comment below.

> +	if (reap_children(-1, 0, fork_kid_pid, MAXKIDS)) {
> +		tst_res(TFAIL, "reap_children() failed");
> +		return;
>  	}

We already failed the test in the reap_children(), so this message is
redundand and we can just return here.

> +static void waitpid_test(void)
> +{
> +	int status;
> +
> +	child_1_pid = SAFE_FORK();
> +	if (child_1_pid == 0) {
> +		do_child_1();
> +	} else {
> +		SAFE_WAITPID(child_1_pid, &status, 0);
> +
> +		child_1_pid = 0;
> +
> +		if (!WIFEXITED(status))
> +			tst_brk(TBROK, "Child 1 exited abnormally");
> +
> +		if (WEXITSTATUS(status) != 0)
> +			tst_res(TFAIL, "Child 1 returned bad status");

This does not correctly propagate TBROK.

What we should do here is similar to the check_child_status() in the
tst_test.c.

I guess that the best course of action would be renaming reap_children()
to tst_reap_children() and remove static so that we can use it in the
tests as well.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [LTP] [PATCH V2 2/4] waitpid07: use the new API
  2016-07-19 14:55       ` [LTP] [PATCH V2 2/4] waitpid07: " Stanislav Kholmanskikh
  2016-07-19 14:55         ` [LTP] [PATCH V2 3/4] waitpid08: " Stanislav Kholmanskikh
@ 2016-08-03 16:12         ` Cyril Hrubis
  1 sibling, 0 replies; 24+ messages in thread
From: Cyril Hrubis @ 2016-08-03 16:12 UTC (permalink / raw)
  To: ltp

Hi!
> +	if (reap_children(-1, WNOHANG, fork_kid_pid, MAXKIDS)) {
> +		tst_res(TFAIL, "reap_children() failed");
> +		return;

Same applies here, the TFAIL here is redundant.

The rest looks good and the same applies to the rest of the patches.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2016-08-03 16:12 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-15 14:39 [LTP] waitpid: new API Stanislav Kholmanskikh
2016-07-15 14:39 ` [LTP] [PATCH 1/8] tst_safe_macros: SAFE_GETPGID Stanislav Kholmanskikh
2016-07-15 14:39 ` [LTP] [PATCH 2/8] waitpid06: use the new API Stanislav Kholmanskikh
2016-07-18 13:05   ` Cyril Hrubis
2016-07-19 14:55     ` [LTP] [PATCH V2 1/4] " Stanislav Kholmanskikh
2016-07-19 14:55       ` [LTP] [PATCH V2 2/4] waitpid07: " Stanislav Kholmanskikh
2016-07-19 14:55         ` [LTP] [PATCH V2 3/4] waitpid08: " Stanislav Kholmanskikh
2016-07-19 14:55           ` [LTP] [PATCH V2 4/4] waitpid11: " Stanislav Kholmanskikh
2016-08-03 16:12         ` [LTP] [PATCH V2 2/4] waitpid07: " Cyril Hrubis
2016-08-03 16:01       ` [LTP] [PATCH V2 1/4] waitpid06: " Cyril Hrubis
2016-08-03 10:19     ` [LTP] [PATCH 2/8] " Stanislav Kholmanskikh
2016-08-03 12:01       ` Cyril Hrubis
2016-07-15 14:39 ` [LTP] [PATCH 3/8] waitpid07: " Stanislav Kholmanskikh
2016-07-15 14:39 ` [LTP] [PATCH 4/8] waitpid09: " Stanislav Kholmanskikh
2016-07-18 14:18   ` Cyril Hrubis
2016-07-19 10:34     ` [LTP] [PATCH V2 " Stanislav Kholmanskikh
2016-07-19 12:41       ` Cyril Hrubis
2016-07-19 14:57         ` Stanislav Kholmanskikh
2016-07-15 14:39 ` [LTP] [PATCH 5/8] waitpid11: " Stanislav Kholmanskikh
2016-07-18 15:01   ` Cyril Hrubis
2016-07-15 14:39 ` [LTP] [PATCH 6/8] waitpid12: " Stanislav Kholmanskikh
2016-07-18 15:07   ` Cyril Hrubis
2016-07-15 14:39 ` [LTP] [PATCH 7/8] waitpid13: " Stanislav Kholmanskikh
2016-07-15 14:39 ` [LTP] [PATCH 8/8] waitpid08: " Stanislav Kholmanskikh

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.