* [LTP] [PATCH V2 01/11] waitpid09: use the new API
2016-08-24 12:27 [LTP] waitpid: new API (part 2) V2 Stanislav Kholmanskikh
@ 2016-08-24 12:27 ` Stanislav Kholmanskikh
2016-08-25 10:49 ` Cyril Hrubis
2016-08-24 12:27 ` [LTP] [PATCH V2 02/11] waitpid10: " Stanislav Kholmanskikh
` (9 subsequent siblings)
10 siblings, 1 reply; 25+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-24 12:27 UTC (permalink / raw)
To: ltp
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
Changes since V1:
* remove code from case0() which is duplicated in case1()
* rewrite the tst_res(TPASS) messages
* use function pointers instead of the switch-case structure
testcases/kernel/syscalls/waitpid/waitpid09.c | 374 ++++++++----------------
1 files changed, 125 insertions(+), 249 deletions(-)
diff --git a/testcases/kernel/syscalls/waitpid/waitpid09.c b/testcases/kernel/syscalls/waitpid/waitpid09.c
index 1339c82..43beeff 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,139 @@
#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;
+ if (pid > 0) {
+ kill(pid, SIGKILL);
+ waitpid(pid, NULL, 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 */
+static void case0(void)
+{
+ pid_t pid, ret;
+ int status;
- /*
- *Check that waitpid with WNOHANG returns zero
- */
- while (((ret = waitpid(pid, &status, WNOHANG))
- != 0) || (errno == EINTR)) {
- if (ret == -1)
- continue;
+ pid = SAFE_FORK();
+ if (pid == 0) {
+ TST_CHECKPOINT_WAIT(0);
- 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
+ exit(0);
+ }
- /* 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;
- }
+ for (;;) {
+ ret = waitpid(pid, &status, WNOHANG);
- while (((ret = waitpid(pid, &status, 0)) != -1)
- || (errno == EINTR)) {
- if (ret == -1)
- continue;
+ if ((ret == -1) && (errno == EINTR))
+ continue;
- if (ret != pid) {
- tst_resm(TFAIL, "Expected %d "
- "got %d as proc id of "
- "child", pid, ret);
- fail = 1;
- }
+ if (ret == 0)
+ break;
- if (status != 0) {
- tst_resm(TFAIL, "status value "
- "got %d expected 0",
- status);
- fail = 1;
- }
- }
- }
+ tst_res(TFAIL, "waitpid(WNOHANG) returned %d, expected 0",
+ ret);
+ cleanup_pid(pid);
+ return;
+ }
- 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);
+ TST_CHECKPOINT_WAKE(0);
+ SAFE_WAITPID(pid, NULL, 0);
- while (((ret = waitpid(pid, &status, WNOHANG))
- != -1) || (errno == EINTR)) {
- if (ret == -1)
- continue;
+ tst_res(TPASS, "waitpid(pid, WNOHANG) = 0 for a running child");
+}
- if (ret != pid) {
- tst_resm(TFAIL, "proc id %d "
- "and retval %d do not "
- "match", pid, ret);
- fail = 1;
- }
+static void case1(void)
+{
+ pid_t pid, ret;
+ int status;
- if (status != 0) {
- tst_resm(TFAIL, "non zero "
- "status received %d",
- status);
- fail = 1;
- }
- }
- }
+ pid = SAFE_FORK();
+ if (pid == 0)
+ exit(0);
- if (fail)
- tst_resm(TFAIL, "case 1 FAILED");
- else
- tst_resm(TPASS, "case 1 PASSED");
+ for (;;) {
+ ret = waitpid(pid, &status, WNOHANG);
- fail = 0;
- ret = waitpid(pid, &status, 0);
+ if ((ret == -1) && (errno == EINTR))
+ continue;
+ if (ret == 0)
+ continue;
- 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;
- }
+ if (ret == pid)
+ break;
- 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;
- }
+ tst_res(TFAIL, "waitpid(WNOHANG) returned %d, expected %d",
+ ret, pid);
+ cleanup_pid(pid);
+ return;
+ }
- if (fail)
- tst_resm(TFAIL, "case 2 FAILED");
- else
- tst_resm(TPASS, "case 2 PASSED");
- }
+ if (!WIFEXITED(status)) {
+ tst_res(TFAIL, "Child exited abnormally");
+ return;
+ }
- 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 (WEXITSTATUS(status) != 0) {
+ tst_res(TFAIL, "Child exited with %d, expected 0",
+ WEXITSTATUS(status));
+ return;
}
- tst_exit();
+ tst_res(TPASS, "waitpid(pid, WNOHANG) = pid for an exited child");
}
-/*
- * setup_sigint()
- * sets up a SIGINT handler
- */
-static void setup_sigint(void)
+static void case2(void)
{
- if ((sig_t) signal(SIGINT, inthandlr) == SIG_ERR) {
- tst_brkm(TFAIL, cleanup, "signal SIGINT failed, errno = %d",
- errno);
+ 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 %s, got %s",
+ tst_strerrno(ECHILD), tst_strerrno(errno));
+ return;
}
-}
-static void setup(void)
-{
- TEST_PAUSE;
+ tst_res(TPASS, "waitpid(-1, 0) = -1 with ECHILD if no children");
}
-static void cleanup(void)
+static void case3(void)
{
-}
+ pid_t ret;
+ int status;
-static void inthandlr(void)
-{
- intintr++;
-}
+ 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 %s, got %s",
+ tst_strerrno(ECHILD), tst_strerrno(errno));
+ return;
+ }
-static void wait_for_parent(void)
-{
- int testvar;
- while (!intintr)
- testvar = 0;
+ tst_res(TPASS, "waitpid(-1, WNOHANG) = -1 with ECHILD if no children");
}
-static void do_exit(void)
-{
- wait_for_parent();
- exit(0);
-}
+static void (*tests[])(void) = { case0, case1, case2, case3 };
-#ifdef UCLINUX
-/*
- * do_exit_uclinux()
- * Sets up SIGINT handler again, then calls do_exit
- */
-static void do_exit_uclinux(void)
+static void waitpid09_test(unsigned int id)
{
- setup_sigint();
- do_exit();
+ tests[id]();
}
-#endif
+
+static struct tst_test test = {
+ .tid = "waitpid09",
+ .forks_child = 1,
+ .needs_checkpoints = 1,
+ .test = waitpid09_test,
+ .tcnt = ARRAY_SIZE(tests),
+};
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [LTP] [PATCH V2 02/11] waitpid10: use the new API
2016-08-24 12:27 [LTP] waitpid: new API (part 2) V2 Stanislav Kholmanskikh
2016-08-24 12:27 ` [LTP] [PATCH V2 01/11] waitpid09: use the new API Stanislav Kholmanskikh
@ 2016-08-24 12:27 ` Stanislav Kholmanskikh
2016-08-25 11:09 ` Cyril Hrubis
2016-08-24 12:27 ` [LTP] [PATCH V2 03/11] Add TST_TRACE Stanislav Kholmanskikh
` (8 subsequent siblings)
10 siblings, 1 reply; 25+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-24 12:27 UTC (permalink / raw)
To: ltp
* update the description to match the actions performed in the test
* make use of the new API
* make use of reap_children() in do_fork()
* put the test function inside do_child_1(), i.e. it forks one more time
than in the original test. It's just for similarity with other test
cases. This change brings no harm or improvements.
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
Changes since V1:
* Update the commit description to explain why I use do_child_1() here
testcases/kernel/syscalls/waitpid/waitpid10.c | 312 ++++---------------------
1 files changed, 47 insertions(+), 265 deletions(-)
diff --git a/testcases/kernel/syscalls/waitpid/waitpid10.c b/testcases/kernel/syscalls/waitpid/waitpid10.c
index d239fda..a505ade 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid10.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid10.c
@@ -14,263 +14,59 @@
* 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
+ * along with this program.
*/
/*
- * 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
*
- * Set up to catch SIGINTs, SIGALRMs, and the real time timer. Until the timer
- * interrupts, do the following. Fork 8 kids, 2 will immediately exit, 2 will
- * sleep, 2 will be compute bound, and 2 will fork another child, both which
- * will do mkdirs on the same directory 50 times. When the timer expires, kill
- * all kids and remove the directory.
+ * Fork 8 kids, 2 will immediately exit, 2 will sleep, 2 will be compute bound
+ * and 2 will fork/reap a child for 50 times.
*/
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
+#include "waitpid_common.h"
-#include <stdio.h>
-#include <signal.h>
-#include <errno.h>
-#include "test.h"
-
-#define MAXKIDS 8
-
-char *TCID = "waitpid10";
-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 do_compute(void);
static void do_fork(void);
static void do_sleep(void);
-static int fail;
-static int fork_kid_pid[MAXKIDS];
-
-#ifdef UCLINUX
-static char *argv0;
-#endif
-
-int main(int ac, char **av)
+static void do_child_1(void)
{
- int kid_count, ret_val, status, nkids;
- int i, j, k, found;
- int wait_kid_pid[MAXKIDS];
-
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
-#ifdef UCLINUX
- argv0 = av[0];
-
- maybe_run_child(&do_exit, "n", 1);
- maybe_run_child(&do_compute, "n", 2);
- maybe_run_child(&do_fork, "n", 3);
- maybe_run_child(&do_sleep, "n", 4);
-#endif
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- fail = 0;
- kid_count = 0;
- intintr = 0;
- for (i = 0; i < MAXKIDS; i++) {
- ret_val = FORK_OR_VFORK();
- if (ret_val < 0)
- tst_brkm(TBROK|TERRNO, cleanup,
- "Fork kid %d failed.", i);
-
- if (ret_val == 0) {
- if (i == 0 || i == 1) {
-#ifdef UCLINUX
- if (self_exec(argv0, "n", 1) < 0)
- tst_brkm(TBROK|TERRNO, cleanup,
- "self_exec %d failed",
- i);
-#else
- do_exit();
-#endif
- }
-
- if (i == 2 || i == 3) {
-#ifdef UCLINUX
- if (self_exec(argv0, "n", 2) < 0)
- tst_brkm(TBROK|TERRNO, cleanup,
- "self_exec %d failed",
- i);
-#else
- do_compute();
-#endif
- }
-
- if (i == 4 || i == 5) {
-#ifdef UCLINUX
- if (self_exec(argv0, "n", 3) < 0)
- tst_brkm(TBROK|TERRNO, cleanup,
- "self_exec %d failed",
- i);
-#else
- do_fork();
-#endif
- }
-
- if (i == 6 || i == 7) {
-#ifdef UCLINUX
- if (self_exec(argv0, "n", 4) < 0)
- tst_brkm(TBROK|TERRNO, cleanup,
- "self_exec %d failed",
- i);
-#else
- do_sleep();
-#endif
-
- }
-
- }
-
- fork_kid_pid[kid_count++] = ret_val;
- }
-
- nkids = kid_count;
-
- /*
- * Now send all the kids a SIGUSR1 to tell them to
- * proceed. We sleep for a while first to allow the
- * children to initialize their "intintr" variables
- * and get set up.
- */
- sleep(15);
+ pid_t pid;
+ int i;
- for (i = 0; i < nkids; i++) {
- if (kill(fork_kid_pid[i], SIGUSR1) < 0) {
- tst_brkm(TBROK|TERRNO, cleanup, "Kill of child "
- "%d failed", i);
- }
- }
+ for (i = 0; i < MAXKIDS; i++) {
+ pid = SAFE_FORK();
+ if (pid == 0) {
+ if (i == 0 || i == 1)
+ do_exit(0);
- /* Wait till all kids have terminated. */
- kid_count = 0;
- errno = 0;
- for (i = 0; i < nkids; i++) {
- while (((ret_val = waitpid(fork_kid_pid[i],
- &status, 0)) != -1)
- || (errno == EINTR)) {
- if (ret_val == -1)
- continue;
+ if (i == 2 || i == 3)
+ do_compute();
- wait_kid_pid[kid_count++] = ret_val;
- }
- }
+ if (i == 4 || i == 5)
+ do_fork();
- /*
- * Check that for every entry in the fork_kid_pid
- * array, there is a matching pid in the
- * wait_kid_pid array.
- */
- for (i = 0; i < MAXKIDS; i++) {
- found = 0;
- for (j = 0; j < MAXKIDS; j++) {
- if (fork_kid_pid[i] == wait_kid_pid[j]) {
- found = 1;
- break;
- }
- }
- if (!found) {
- tst_resm(TFAIL, "Did not find a "
- "wait_kid_pid for the "
- "fork_kid_pid of %d",
- fork_kid_pid[i]);
- for (k = 0; k < nkids; 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 (i == 6 || i == 7)
+ do_sleep();
}
- memset(fork_kid_pid, 0, sizeof(fork_kid_pid));
-
- if (fail)
- tst_resm(TFAIL, "Test FAILED");
- else
- tst_resm(TPASS, "Test PASSED");
+ fork_kid_pid[i] = pid;
}
- cleanup();
- tst_exit();
-}
-
-static void setup(void)
-{
- struct sigaction act;
-
- tst_sig(FORK, DEF_HANDLER, cleanup);
+ TST_CHECKPOINT_WAKE2(0, MAXKIDS);
- TEST_PAUSE;
+ if (reap_children(0, 0, fork_kid_pid, MAXKIDS))
+ return;
- act.sa_handler = inthandlr;
- act.sa_flags = SA_RESTART;
- sigemptyset(&act.sa_mask);
-
- if (sigaction(SIGUSR1, &act, NULL) < 0)
- tst_brkm(TBROK|TERRNO, cleanup,
- "sigaction(SIGUSR1, ...) failed");
-
- intintr = 0;
-
-}
-
-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++;
-}
-
-static void wait_for_parent(void)
-{
- while (!intintr)
- usleep(100);
-}
-
-static void do_exit(void)
-{
- wait_for_parent();
- exit(3);
+ tst_res(TPASS, "Test PASSED");
}
static void do_compute(void)
{
int i;
- wait_for_parent();
+ TST_CHECKPOINT_WAIT(0);
for (i = 0; i < 100000; i++) ;
for (i = 0; i < 100000; i++) ;
@@ -283,57 +79,43 @@ static void do_compute(void)
for (i = 0; i < 100000; i++) ;
for (i = 0; i < 100000; i++) ;
- exit(4);
+ exit(3);
}
static void do_fork(void)
{
- int fork_pid, wait_pid;
- int status, i;
+ pid_t fork_pid;
+ int i;
- wait_for_parent();
+ TST_CHECKPOINT_WAIT(0);
for (i = 0; i < 50; i++) {
- fork_pid = FORK_OR_VFORK();
- if (fork_pid < 0) {
- tst_brkm(TBROK|TERRNO, NULL, "Fork failed");
- }
- if (fork_pid == 0) {
-#ifdef UCLINUX
- if (self_exec(argv0, "n", 1) < 0) {
- tst_brkm(TFAIL, NULL,
- "do_fork self_exec failed");
- }
-#else
- do_exit();
-#endif
- }
-
- errno = 0;
- while (((wait_pid = waitpid(fork_pid, &status, 0)) != -1) ||
- (errno == EINTR)) {
- if (wait_pid == -1)
- continue;
+ fork_pid = SAFE_FORK();
+ if (fork_pid == 0)
+ exit(3);
- if (fork_pid != wait_pid) {
- tst_resm(TFAIL, "Didnt get a pid returned "
- "from waitpid that matches the one "
- "returned by fork");
- tst_resm(TFAIL, "fork pid = %d, wait pid = "
- "%d", fork_pid, wait_pid);
- fail = 1;
- }
- }
+ if (reap_children(fork_pid, 0, &fork_pid, 1))
+ break;
}
- exit(4);
+ exit(3);
}
static void do_sleep(void)
{
- wait_for_parent();
+ TST_CHECKPOINT_WAIT(0);
+
sleep(1);
sleep(1);
- exit(4);
+ exit(3);
}
+
+static struct tst_test test = {
+ .tid = "waitpid10",
+ .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] 25+ messages in thread* [LTP] [PATCH V2 03/11] Add TST_TRACE
2016-08-24 12:27 [LTP] waitpid: new API (part 2) V2 Stanislav Kholmanskikh
2016-08-24 12:27 ` [LTP] [PATCH V2 01/11] waitpid09: use the new API Stanislav Kholmanskikh
2016-08-24 12:27 ` [LTP] [PATCH V2 02/11] waitpid10: " Stanislav Kholmanskikh
@ 2016-08-24 12:27 ` Stanislav Kholmanskikh
2016-08-25 11:15 ` Cyril Hrubis
2016-08-24 12:27 ` [LTP] [PATCH V2 04/11] syscalls/waitpid: call reap_children() via TST_TRACE() Stanislav Kholmanskikh
` (7 subsequent siblings)
10 siblings, 1 reply; 25+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-24 12:27 UTC (permalink / raw)
To: ltp
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
This is a new patch in the series.
doc/test-writing-guidelines.txt | 38 ++++++++++++++++++++++++++++++++++++++
include/tst_test.h | 4 ++++
2 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
index 740e90c..3a3e644 100644
--- a/doc/test-writing-guidelines.txt
+++ b/doc/test-writing-guidelines.txt
@@ -1226,6 +1226,44 @@ the rest of the LTP test binaries.
WARNING: All identifiers starting with TST_ or tst_ are reserved for the
'test.sh' library.
+2.2.22 Code path tracing
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+'tst_res' is a macro, so on when you define a function in one file:
+
+[source,c]
+-------------------------------------------------------------------------------
+int do_action(void)
+{
+ ...
+
+ if (ok) {
+ tst_res(TPASS, "...");
+ return 0;
+ } else {
+ tst_res(TFAIL, "...");
+ return -1;
+ }
+}
+-------------------------------------------------------------------------------
+
+and call it from another file, the file and line reported by 'tst_res' in this
+function will be from the former file.
+
+'TST_TRACE' can make the analysis of such situations easier. It's a macro which
+inserts a call to 'tst_res(TINFO, ...)' in case its argument is not zero.
+In this call to 'tst_res(TINFO, ...)' the file and line will be expanded using
+the actual location of 'TST_TRACE'.
+
+[source,c]
+-------------------------------------------------------------------------------
+#include "tst_test.h"
+
+if (TST_TRACE(do_action())) {
+ ...
+}
+-------------------------------------------------------------------------------
+
2.3.1 Basic shell test structure
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/include/tst_test.h b/include/tst_test.h
index 3e2ff5b..eb3f751 100644
--- a/include/tst_test.h
+++ b/include/tst_test.h
@@ -59,6 +59,10 @@ pid_t safe_fork(const char *filename, unsigned int lineno);
#define SAFE_FORK() \
safe_fork(__FILE__, __LINE__)
+#define TST_TRACE(expr) \
+ ({int ret = expr; \
+ ret != 0 ? tst_res(TINFO, #expr " failed"), ret : ret; })
+
#include "tst_safe_macros.h"
#include "tst_safe_file_ops.h"
#include "tst_safe_net.h"
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [LTP] [PATCH V2 03/11] Add TST_TRACE
2016-08-24 12:27 ` [LTP] [PATCH V2 03/11] Add TST_TRACE Stanislav Kholmanskikh
@ 2016-08-25 11:15 ` Cyril Hrubis
2016-08-25 12:09 ` Stanislav Kholmanskikh
0 siblings, 1 reply; 25+ messages in thread
From: Cyril Hrubis @ 2016-08-25 11:15 UTC (permalink / raw)
To: ltp
Hi!
> +'TST_TRACE' can make the analysis of such situations easier. It's a macro which
> +inserts a call to 'tst_res(TINFO, ...)' in case its argument is not zero.
^
"evaluates to non-zero"
would be more clear in
this case
> +In this call to 'tst_res(TINFO, ...)' the file and line will be expanded using
> +the actual location of 'TST_TRACE'.
> +
> +[source,c]
> +-------------------------------------------------------------------------------
> +#include "tst_test.h"
> +
> +if (TST_TRACE(do_action())) {
> + ...
> +}
> +-------------------------------------------------------------------------------
Maybe we should also include example test output here. Otherise the
description looks good to me.
> 2.3.1 Basic shell test structure
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> diff --git a/include/tst_test.h b/include/tst_test.h
> index 3e2ff5b..eb3f751 100644
> --- a/include/tst_test.h
> +++ b/include/tst_test.h
> @@ -59,6 +59,10 @@ pid_t safe_fork(const char *filename, unsigned int lineno);
> #define SAFE_FORK() \
> safe_fork(__FILE__, __LINE__)
>
> +#define TST_TRACE(expr) \
> + ({int ret = expr; \
> + ret != 0 ? tst_res(TINFO, #expr " failed"), ret : ret; })
> +
I would format this to something as:
#define TST_TRACE(expr) \
({int ret = expr; \
ret != 0 ? tst_res(TINFO, #expr " failed"), ret : ret; }) \
But that is very minor.
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 25+ messages in thread* [LTP] [PATCH V2 03/11] Add TST_TRACE
2016-08-25 11:15 ` Cyril Hrubis
@ 2016-08-25 12:09 ` Stanislav Kholmanskikh
0 siblings, 0 replies; 25+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-25 12:09 UTC (permalink / raw)
To: ltp
On 08/25/2016 02:15 PM, Cyril Hrubis wrote:
> Hi!
>> +'TST_TRACE' can make the analysis of such situations easier. It's a macro which
>> +inserts a call to 'tst_res(TINFO, ...)' in case its argument is not zero.
> ^
> "evaluates to non-zero"
>
> would be more clear in
> this case
>
Ok.
>> +In this call to 'tst_res(TINFO, ...)' the file and line will be expanded using
>> +the actual location of 'TST_TRACE'.
>> +
>> +[source,c]
>> +-------------------------------------------------------------------------------
>> +#include "tst_test.h"
>> +
>> +if (TST_TRACE(do_action())) {
>> + ...
>> +}
>> +-------------------------------------------------------------------------------
>
> Maybe we should also include example test output here. Otherise the
> description looks good to me.
Ok. Will add one.
>
>> 2.3.1 Basic shell test structure
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>
>> diff --git a/include/tst_test.h b/include/tst_test.h
>> index 3e2ff5b..eb3f751 100644
>> --- a/include/tst_test.h
>> +++ b/include/tst_test.h
>> @@ -59,6 +59,10 @@ pid_t safe_fork(const char *filename, unsigned int lineno);
>> #define SAFE_FORK() \
>> safe_fork(__FILE__, __LINE__)
>>
>> +#define TST_TRACE(expr) \
>> + ({int ret = expr; \
>> + ret != 0 ? tst_res(TINFO, #expr " failed"), ret : ret; })
>> +
>
> I would format this to something as:
>
> #define TST_TRACE(expr) \
> ({int ret = expr; \
> ret != 0 ? tst_res(TINFO, #expr " failed"), ret : ret; }) \
>
> But that is very minor.
No problem, will do it.
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* [LTP] [PATCH V2 04/11] syscalls/waitpid: call reap_children() via TST_TRACE()
2016-08-24 12:27 [LTP] waitpid: new API (part 2) V2 Stanislav Kholmanskikh
` (2 preceding siblings ...)
2016-08-24 12:27 ` [LTP] [PATCH V2 03/11] Add TST_TRACE Stanislav Kholmanskikh
@ 2016-08-24 12:27 ` Stanislav Kholmanskikh
2016-08-25 11:20 ` Cyril Hrubis
2016-08-24 12:27 ` [LTP] [PATCH V2 05/11] syscalls/waitpid: implement waitpid_ret_test() Stanislav Kholmanskikh
` (6 subsequent siblings)
10 siblings, 1 reply; 25+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-24 12:27 UTC (permalink / raw)
To: ltp
To make the tracing of the failed code path easier.
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
This is a new patch in the series.
testcases/kernel/syscalls/waitpid/waitpid06.c | 2 +-
testcases/kernel/syscalls/waitpid/waitpid07.c | 2 +-
testcases/kernel/syscalls/waitpid/waitpid08.c | 2 +-
testcases/kernel/syscalls/waitpid/waitpid10.c | 4 ++--
testcases/kernel/syscalls/waitpid/waitpid11.c | 5 +++--
5 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/testcases/kernel/syscalls/waitpid/waitpid06.c b/testcases/kernel/syscalls/waitpid/waitpid06.c
index 66d5ebc..20c30e1 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid06.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid06.c
@@ -48,7 +48,7 @@ static void do_child_1(void)
TST_CHECKPOINT_WAKE2(0, MAXKIDS);
- if (reap_children(-1, 0, fork_kid_pid, MAXKIDS))
+ if (TST_TRACE(reap_children(-1, 0, fork_kid_pid, MAXKIDS)))
return;
tst_res(TPASS, "Test PASSED");
diff --git a/testcases/kernel/syscalls/waitpid/waitpid07.c b/testcases/kernel/syscalls/waitpid/waitpid07.c
index 74da914..47ebf9a 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid07.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid07.c
@@ -57,7 +57,7 @@ static void do_child_1(void)
TST_CHECKPOINT_WAKE2(0, MAXKIDS);
- if (reap_children(-1, WNOHANG, fork_kid_pid, MAXKIDS))
+ if (TST_TRACE(reap_children(-1, WNOHANG, fork_kid_pid, MAXKIDS)))
return;
tst_res(TPASS, "Test PASSED");
diff --git a/testcases/kernel/syscalls/waitpid/waitpid08.c b/testcases/kernel/syscalls/waitpid/waitpid08.c
index 0f0ee9d..b95a308 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid08.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid08.c
@@ -61,7 +61,7 @@ static void do_child_1(void)
TST_CHECKPOINT_WAKE2(0, MAXKIDS);
- if (reap_children(-1, WUNTRACED, fork_kid_pid, MAXKIDS))
+ if (TST_TRACE(reap_children(-1, WUNTRACED, fork_kid_pid, MAXKIDS)))
return;
/*
diff --git a/testcases/kernel/syscalls/waitpid/waitpid10.c b/testcases/kernel/syscalls/waitpid/waitpid10.c
index a505ade..90b3800 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid10.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid10.c
@@ -56,7 +56,7 @@ static void do_child_1(void)
TST_CHECKPOINT_WAKE2(0, MAXKIDS);
- if (reap_children(0, 0, fork_kid_pid, MAXKIDS))
+ if (TST_TRACE(reap_children(0, 0, fork_kid_pid, MAXKIDS)))
return;
tst_res(TPASS, "Test PASSED");
@@ -94,7 +94,7 @@ static void do_fork(void)
if (fork_pid == 0)
exit(3);
- if (reap_children(fork_pid, 0, &fork_pid, 1))
+ if (TST_TRACE(reap_children(fork_pid, 0, &fork_pid, 1)))
break;
}
diff --git a/testcases/kernel/syscalls/waitpid/waitpid11.c b/testcases/kernel/syscalls/waitpid/waitpid11.c
index 9b51e04..1067bca 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid11.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid11.c
@@ -50,11 +50,12 @@ static void do_child_1(void)
TST_CHECKPOINT_WAKE2(0, MAXKIDS);
- if (reap_children(0, 0, fork_kid_pid + (MAXKIDS / 2), MAXKIDS / 2))
+ if (TST_TRACE(reap_children(0, 0, fork_kid_pid + (MAXKIDS / 2),
+ MAXKIDS / 2)))
return;
/* Make sure can pickup children in a diff. process group */
- if (reap_children(-group, 0, fork_kid_pid, MAXKIDS / 2))
+ if (TST_TRACE(reap_children(-group, 0, fork_kid_pid, MAXKIDS / 2)))
return;
tst_res(TPASS, "Test PASSED");
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [LTP] [PATCH V2 04/11] syscalls/waitpid: call reap_children() via TST_TRACE()
2016-08-24 12:27 ` [LTP] [PATCH V2 04/11] syscalls/waitpid: call reap_children() via TST_TRACE() Stanislav Kholmanskikh
@ 2016-08-25 11:20 ` Cyril Hrubis
2016-08-25 11:56 ` Stanislav Kholmanskikh
0 siblings, 1 reply; 25+ messages in thread
From: Cyril Hrubis @ 2016-08-25 11:20 UTC (permalink / raw)
To: ltp
Hi!
This is obviously correct.
> diff --git a/testcases/kernel/syscalls/waitpid/waitpid11.c b/testcases/kernel/syscalls/waitpid/waitpid11.c
> index 9b51e04..1067bca 100644
> --- a/testcases/kernel/syscalls/waitpid/waitpid11.c
> +++ b/testcases/kernel/syscalls/waitpid/waitpid11.c
> @@ -50,11 +50,12 @@ static void do_child_1(void)
>
> TST_CHECKPOINT_WAKE2(0, MAXKIDS);
>
> - if (reap_children(0, 0, fork_kid_pid + (MAXKIDS / 2), MAXKIDS / 2))
> + if (TST_TRACE(reap_children(0, 0, fork_kid_pid + (MAXKIDS / 2),
> + MAXKIDS / 2)))
> return;
Hmm, if we drop the useless parenthesis and spaces around / we will fit
into 80 chars:
if (TST_TRACE(reap_children(0, 0, fork_kid_pid + MAXKIDS/2, MAXKIDS/2)))
return;
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 25+ messages in thread
* [LTP] [PATCH V2 04/11] syscalls/waitpid: call reap_children() via TST_TRACE()
2016-08-25 11:20 ` Cyril Hrubis
@ 2016-08-25 11:56 ` Stanislav Kholmanskikh
0 siblings, 0 replies; 25+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-25 11:56 UTC (permalink / raw)
To: ltp
On 08/25/2016 02:20 PM, Cyril Hrubis wrote:
> Hi!
> This is obviously correct.
>
>> diff --git a/testcases/kernel/syscalls/waitpid/waitpid11.c b/testcases/kernel/syscalls/waitpid/waitpid11.c
>> index 9b51e04..1067bca 100644
>> --- a/testcases/kernel/syscalls/waitpid/waitpid11.c
>> +++ b/testcases/kernel/syscalls/waitpid/waitpid11.c
>> @@ -50,11 +50,12 @@ static void do_child_1(void)
>>
>> TST_CHECKPOINT_WAKE2(0, MAXKIDS);
>>
>> - if (reap_children(0, 0, fork_kid_pid + (MAXKIDS / 2), MAXKIDS / 2))
>> + if (TST_TRACE(reap_children(0, 0, fork_kid_pid + (MAXKIDS / 2),
>> + MAXKIDS / 2)))
>> return;
>
> Hmm, if we drop the useless parenthesis and spaces around / we will fit
> into 80 chars:
>
> if (TST_TRACE(reap_children(0, 0, fork_kid_pid + MAXKIDS/2, MAXKIDS/2)))
> return;
>
Ok.
^ permalink raw reply [flat|nested] 25+ messages in thread
* [LTP] [PATCH V2 05/11] syscalls/waitpid: implement waitpid_ret_test()
2016-08-24 12:27 [LTP] waitpid: new API (part 2) V2 Stanislav Kholmanskikh
` (3 preceding siblings ...)
2016-08-24 12:27 ` [LTP] [PATCH V2 04/11] syscalls/waitpid: call reap_children() via TST_TRACE() Stanislav Kholmanskikh
@ 2016-08-24 12:27 ` Stanislav Kholmanskikh
2016-08-25 11:28 ` Cyril Hrubis
2016-08-24 12:27 ` [LTP] [PATCH V2 06/11] syscalls/waitpid: make reap_children() fail if errno is not ECHILD Stanislav Kholmanskikh
` (5 subsequent siblings)
10 siblings, 1 reply; 25+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-24 12:27 UTC (permalink / raw)
To: ltp
Several test cases call waitpid() and then verify the returned
value and errno set. Moved this code into a function.
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
Changes since V1:
* Use TST_TRACE
testcases/kernel/syscalls/waitpid/waitpid07.c | 6 +---
testcases/kernel/syscalls/waitpid/waitpid08.c | 25 +---------------
testcases/kernel/syscalls/waitpid/waitpid_common.h | 29 ++++++++++++++++++++
3 files changed, 32 insertions(+), 28 deletions(-)
diff --git a/testcases/kernel/syscalls/waitpid/waitpid07.c b/testcases/kernel/syscalls/waitpid/waitpid07.c
index 47ebf9a..9166fbe 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid07.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid07.c
@@ -48,12 +48,8 @@ static void do_child_1(void)
}
/* Check that waitpid with WNOHANG returns zero */
- pid = waitpid(-1, &status, WNOHANG);
- if (pid != 0) {
- tst_res(TFAIL, "waitpid() returned %d, expected 0",
- pid);
+ if (TST_TRACE(waitpid_ret_test(-1, &status, WNOHANG, 0, 0)))
return;
- }
TST_CHECKPOINT_WAKE2(0, MAXKIDS);
diff --git a/testcases/kernel/syscalls/waitpid/waitpid08.c b/testcases/kernel/syscalls/waitpid/waitpid08.c
index b95a308..6c8d3b9 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid08.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid08.c
@@ -51,36 +51,15 @@ static void do_child_1(void)
/* Check that waitpid with WNOHANG|WUNTRACED returns
* zero
*/
- pid = waitpid(-1, &status, WNOHANG | WUNTRACED);
- if (pid != 0) {
- tst_res(TFAIL,
- "waitpid(WNOHANG | WUNTRACED) returned %d, expected 0",
- pid);
+ if (TST_TRACE(waitpid_ret_test(-1, &status, WNOHANG | WUNTRACED,
+ 0, 0)))
return;
- }
TST_CHECKPOINT_WAKE2(0, MAXKIDS);
if (TST_TRACE(reap_children(-1, WUNTRACED, fork_kid_pid, MAXKIDS)))
return;
- /*
- * Check that waitpid(WUNTRACED) returns -1 when no
- * stopped children
- */
- pid = waitpid(-1, &status, WUNTRACED);
- if (pid != -1) {
- tst_res(TFAIL, "waitpid(WUNTRACED) returned %d, expected -1",
- pid);
- return;
- }
-
- if (errno != ECHILD) {
- tst_res(TFAIL, "waitpid(WUNTRACED) set errno %s, expected %s",
- tst_strerrno(errno), tst_strerrno(ECHILD));
- return;
- }
-
tst_res(TPASS, "Test PASSED");
}
diff --git a/testcases/kernel/syscalls/waitpid/waitpid_common.h b/testcases/kernel/syscalls/waitpid/waitpid_common.h
index 008577a..f5e9519 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid_common.h
+++ b/testcases/kernel/syscalls/waitpid/waitpid_common.h
@@ -75,6 +75,35 @@ static void do_exit(int stop)
exit(3);
}
+static int waitpid_errno_check(int err, int exp_err)
+{
+ if (err != exp_err) {
+ tst_res(TFAIL, "waitpid() set errno to %s, expected %s",
+ tst_strerrno(err), tst_strerrno(exp_err));
+ return -1;
+ }
+
+ return 0;
+}
+
+int waitpid_ret_test(pid_t wp_pid, int *wp_status, int wp_opts,
+ pid_t wp_ret, int wp_errno)
+{
+ pid_t ret;
+
+ ret = waitpid(wp_pid, wp_status, wp_opts);
+ if (ret != wp_ret) {
+ tst_res(TFAIL, "waitpid() returned %d, expected %d",
+ ret, wp_ret);
+ return -1;
+ }
+
+ if ((ret == -1) && waitpid_errno_check(errno, wp_errno))
+ return -1;
+
+ return 0;
+}
+
static int reap_children(pid_t wp_pid, int wp_opts, pid_t *children, int len)
{
pid_t pid;
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [LTP] [PATCH V2 05/11] syscalls/waitpid: implement waitpid_ret_test()
2016-08-24 12:27 ` [LTP] [PATCH V2 05/11] syscalls/waitpid: implement waitpid_ret_test() Stanislav Kholmanskikh
@ 2016-08-25 11:28 ` Cyril Hrubis
2016-08-25 12:00 ` Stanislav Kholmanskikh
0 siblings, 1 reply; 25+ messages in thread
From: Cyril Hrubis @ 2016-08-25 11:28 UTC (permalink / raw)
To: ltp
Hi!
> + if (TST_TRACE(waitpid_ret_test(-1, &status, WNOHANG | WUNTRACED,
> + 0, 0)))
> return;
Hmm, I know this is merely cosmetic but as far as I can tell the line
fits into 80 chars. Or did checkpatch complained since it has precisely
80 chars?
If that is the case what about shortening the waitpid_ret_test() to
waitpid_test()?
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 25+ messages in thread
* [LTP] [PATCH V2 05/11] syscalls/waitpid: implement waitpid_ret_test()
2016-08-25 11:28 ` Cyril Hrubis
@ 2016-08-25 12:00 ` Stanislav Kholmanskikh
0 siblings, 0 replies; 25+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-25 12:00 UTC (permalink / raw)
To: ltp
On 08/25/2016 02:28 PM, Cyril Hrubis wrote:
> Hi!
>> + if (TST_TRACE(waitpid_ret_test(-1, &status, WNOHANG | WUNTRACED,
>> + 0, 0)))
>> return;
>
> Hmm, I know this is merely cosmetic but as far as I can tell the line
> fits into 80 chars. Or did checkpatch complained since it has precisely
> 80 chars?
No, it didn't complain about that. I'll put this all on one line.
>
> If that is the case what about shortening the waitpid_ret_test() to
> waitpid_test()?
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* [LTP] [PATCH V2 06/11] syscalls/waitpid: make reap_children() fail if errno is not ECHILD
2016-08-24 12:27 [LTP] waitpid: new API (part 2) V2 Stanislav Kholmanskikh
` (4 preceding siblings ...)
2016-08-24 12:27 ` [LTP] [PATCH V2 05/11] syscalls/waitpid: implement waitpid_ret_test() Stanislav Kholmanskikh
@ 2016-08-24 12:27 ` Stanislav Kholmanskikh
2016-08-24 12:27 ` [LTP] [PATCH V2 07/11] waitpid11: update the description Stanislav Kholmanskikh
` (4 subsequent siblings)
10 siblings, 0 replies; 25+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-24 12:27 UTC (permalink / raw)
To: ltp
We expect that waitpid() may fail only with EINTR or ECHILD.
All other errno values signal about an error.
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
No changes since V1.
testcases/kernel/syscalls/waitpid/waitpid_common.h | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/testcases/kernel/syscalls/waitpid/waitpid_common.h b/testcases/kernel/syscalls/waitpid/waitpid_common.h
index f5e9519..f724a17 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid_common.h
+++ b/testcases/kernel/syscalls/waitpid/waitpid_common.h
@@ -117,6 +117,9 @@ static int reap_children(pid_t wp_pid, int wp_opts, pid_t *children, int len)
if (errno == EINTR)
continue;
+ if (waitpid_errno_check(errno, ECHILD))
+ return -1;
+
break;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [LTP] [PATCH V2 07/11] waitpid11: update the description
2016-08-24 12:27 [LTP] waitpid: new API (part 2) V2 Stanislav Kholmanskikh
` (5 preceding siblings ...)
2016-08-24 12:27 ` [LTP] [PATCH V2 06/11] syscalls/waitpid: make reap_children() fail if errno is not ECHILD Stanislav Kholmanskikh
@ 2016-08-24 12:27 ` Stanislav Kholmanskikh
2016-08-24 12:27 ` [LTP] [PATCH V2 08/11] waitpid12: use the new API Stanislav Kholmanskikh
` (3 subsequent siblings)
10 siblings, 0 replies; 25+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-24 12:27 UTC (permalink / raw)
To: ltp
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
No changes since V1.
testcases/kernel/syscalls/waitpid/waitpid11.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/testcases/kernel/syscalls/waitpid/waitpid11.c b/testcases/kernel/syscalls/waitpid/waitpid11.c
index 1067bca..532c1db 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid11.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid11.c
@@ -25,7 +25,7 @@
* Tests to see if pids returned from fork and waitpid are same
*
* ALGORITHM
- * Check proper functioning of waitpid with pid = -1 and arg = 0
+ * Check proper functioning of waitpid with pid = 0 and < -1 with arg 0
*/
#include "waitpid_common.h"
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [LTP] [PATCH V2 08/11] waitpid12: use the new API
2016-08-24 12:27 [LTP] waitpid: new API (part 2) V2 Stanislav Kholmanskikh
` (6 preceding siblings ...)
2016-08-24 12:27 ` [LTP] [PATCH V2 07/11] waitpid11: update the description Stanislav Kholmanskikh
@ 2016-08-24 12:27 ` Stanislav Kholmanskikh
2016-08-24 12:27 ` [LTP] [PATCH V2 09/11] syscalls/waitpid: adapt reap_children() to test stopped children Stanislav Kholmanskikh
` (2 subsequent siblings)
10 siblings, 0 replies; 25+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-24 12:27 UTC (permalink / raw)
To: ltp
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
No changes since V1.
testcases/kernel/syscalls/waitpid/waitpid12.c | 353 ++++---------------------
1 files changed, 52 insertions(+), 301 deletions(-)
diff --git a/testcases/kernel/syscalls/waitpid/waitpid12.c b/testcases/kernel/syscalls/waitpid/waitpid12.c
index bf64662..b2db49d 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid12.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid12.c
@@ -1,329 +1,80 @@
/*
+ * 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 = 0 and < -1 with 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();
-
- 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();
-
- 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(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);
-
- /* 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);
- 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);
-
- /*
- * Wait till all kids have terminated. Stash away their
- * pid's 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 "
- "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 = (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 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;
- }
- }
+ pid_t pid, group;
+ int i;
+ int status;
- 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;
- }
+ group = SAFE_GETPGID(0);
- /* Make sure can pickup children in a diff. process group */
+ for (i = 0; i < MAXKIDS; i++) {
+ if (i == (MAXKIDS / 2))
+ SAFE_SETPGID(0, 0);
- kid_count = 0;
- errno = 0;
- while (((ret_val = waitpid(-(group1), &status, WNOHANG)) !=
- -1) || (errno == EINTR)) {
- if (ret_val == -1 || ret_val == 0)
- 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 = 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 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] = "
- "%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 (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 (TST_TRACE(waitpid_ret_test(0, &status, WNOHANG, 0, 0)))
+ return;
- if (fail)
- tst_resm(TFAIL, "Test FAILED");
- else
- tst_resm(TPASS, "Test PASSED");
+ if (TST_TRACE(waitpid_ret_test(-group, &status, WNOHANG, 0, 0)))
+ return;
- tst_exit();
-}
+ TST_CHECKPOINT_WAKE2(0, MAXKIDS);
-static void setup_sigint(void)
-{
- if (signal(SIGINT, inthandlr) == SIG_ERR)
- tst_brkm(TFAIL | TERRNO, NULL, "signal SIGINT failed");
-}
+ if (TST_TRACE(reap_children(0, WNOHANG, fork_kid_pid + (MAXKIDS / 2),
+ MAXKIDS / 2)))
+ return;
-static void setup(void)
-{
- tst_sig(FORK, DEF_HANDLER, cleanup);
+ if (TST_TRACE(reap_children(-group, WNOHANG, fork_kid_pid,
+ MAXKIDS / 2)))
+ return;
- 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);
-}
-
-#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,
+ .setup = waitpid_setup,
+ .cleanup = waitpid_cleanup,
+ .test_all = waitpid_test,
+};
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [LTP] [PATCH V2 09/11] syscalls/waitpid: adapt reap_children() to test stopped children
2016-08-24 12:27 [LTP] waitpid: new API (part 2) V2 Stanislav Kholmanskikh
` (7 preceding siblings ...)
2016-08-24 12:27 ` [LTP] [PATCH V2 08/11] waitpid12: use the new API Stanislav Kholmanskikh
@ 2016-08-24 12:27 ` Stanislav Kholmanskikh
2016-08-25 11:39 ` Cyril Hrubis
2016-08-24 12:27 ` [LTP] [PATCH V2 10/11] waitpid13: use the new API Stanislav Kholmanskikh
2016-08-24 12:27 ` [LTP] [PATCH V2 11/11] waitpid08: test stopped children Stanislav Kholmanskikh
10 siblings, 1 reply; 25+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-24 12:27 UTC (permalink / raw)
To: ltp
If the pid returned by waitpid() is the pid of a stopped child,
we send it the SIGCONT signal.
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
This is a new patch in the series, extracted from V1 of waitpid13.c
testcases/kernel/syscalls/waitpid/waitpid_common.h | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/testcases/kernel/syscalls/waitpid/waitpid_common.h b/testcases/kernel/syscalls/waitpid/waitpid_common.h
index f724a17..7b67a06 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid_common.h
+++ b/testcases/kernel/syscalls/waitpid/waitpid_common.h
@@ -131,6 +131,23 @@ static int reap_children(pid_t wp_pid, int wp_opts, pid_t *children, int len)
return -1;
}
+ if (WIFSTOPPED(status)) {
+ if (WSTOPSIG(status) != SIGSTOP) {
+ tst_res(TFAIL,
+ "Pid %d: expected SIGSTOP, got %d",
+ pid, WSTOPSIG(status));
+ return -1;
+ }
+
+ if (kill(pid, SIGCONT) < 0) {
+ tst_res(TFAIL | TERRNO,
+ "kill(%d, SIGCONT) failed", pid);
+ return -1;
+ }
+
+ continue;
+ }
+
for (i = 0; i < len; i++) {
if (pid == children[i]) {
children[i] = 0;
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [LTP] [PATCH V2 09/11] syscalls/waitpid: adapt reap_children() to test stopped children
2016-08-24 12:27 ` [LTP] [PATCH V2 09/11] syscalls/waitpid: adapt reap_children() to test stopped children Stanislav Kholmanskikh
@ 2016-08-25 11:39 ` Cyril Hrubis
2016-08-25 12:02 ` Stanislav Kholmanskikh
0 siblings, 1 reply; 25+ messages in thread
From: Cyril Hrubis @ 2016-08-25 11:39 UTC (permalink / raw)
To: ltp
Hi!
> If the pid returned by waitpid() is the pid of a stopped child,
> we send it the SIGCONT signal.
>
> Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
> ---
> This is a new patch in the series, extracted from V1 of waitpid13.c
>
> testcases/kernel/syscalls/waitpid/waitpid_common.h | 17 +++++++++++++++++
> 1 files changed, 17 insertions(+), 0 deletions(-)
>
> diff --git a/testcases/kernel/syscalls/waitpid/waitpid_common.h b/testcases/kernel/syscalls/waitpid/waitpid_common.h
> index f724a17..7b67a06 100644
> --- a/testcases/kernel/syscalls/waitpid/waitpid_common.h
> +++ b/testcases/kernel/syscalls/waitpid/waitpid_common.h
> @@ -131,6 +131,23 @@ static int reap_children(pid_t wp_pid, int wp_opts, pid_t *children, int len)
> return -1;
> }
>
> + if (WIFSTOPPED(status)) {
> + if (WSTOPSIG(status) != SIGSTOP) {
> + tst_res(TFAIL,
> + "Pid %d: expected SIGSTOP, got %d",
> + pid, WSTOPSIG(status));
> + return -1;
> + }
Maybe we should print tst_res(TINFO, "Seding SIGCONT to %i", pid); here.
> + if (kill(pid, SIGCONT) < 0) {
> + tst_res(TFAIL | TERRNO,
> + "kill(%d, SIGCONT) failed", pid);
> + return -1;
> + }
> +
> + continue;
> + }
> +
> for (i = 0; i < len; i++) {
> if (pid == children[i]) {
> children[i] = 0;
Otherwise it looks good.
I guess that there is no real chance that some of the children in
testcases that use this function would be SIGSTOPed accidentally and
this code will make that bug disappear...
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 25+ messages in thread* [LTP] [PATCH V2 09/11] syscalls/waitpid: adapt reap_children() to test stopped children
2016-08-25 11:39 ` Cyril Hrubis
@ 2016-08-25 12:02 ` Stanislav Kholmanskikh
0 siblings, 0 replies; 25+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-25 12:02 UTC (permalink / raw)
To: ltp
On 08/25/2016 02:39 PM, Cyril Hrubis wrote:
> Hi!
>> If the pid returned by waitpid() is the pid of a stopped child,
>> we send it the SIGCONT signal.
>>
>> Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
>> ---
>> This is a new patch in the series, extracted from V1 of waitpid13.c
>>
>> testcases/kernel/syscalls/waitpid/waitpid_common.h | 17 +++++++++++++++++
>> 1 files changed, 17 insertions(+), 0 deletions(-)
>>
>> diff --git a/testcases/kernel/syscalls/waitpid/waitpid_common.h b/testcases/kernel/syscalls/waitpid/waitpid_common.h
>> index f724a17..7b67a06 100644
>> --- a/testcases/kernel/syscalls/waitpid/waitpid_common.h
>> +++ b/testcases/kernel/syscalls/waitpid/waitpid_common.h
>> @@ -131,6 +131,23 @@ static int reap_children(pid_t wp_pid, int wp_opts, pid_t *children, int len)
>> return -1;
>> }
>>
>> + if (WIFSTOPPED(status)) {
>> + if (WSTOPSIG(status) != SIGSTOP) {
>> + tst_res(TFAIL,
>> + "Pid %d: expected SIGSTOP, got %d",
>> + pid, WSTOPSIG(status));
>> + return -1;
>> + }
>
> Maybe we should print tst_res(TINFO, "Seding SIGCONT to %i", pid); here.
Ok.
>
>> + if (kill(pid, SIGCONT) < 0) {
>> + tst_res(TFAIL | TERRNO,
>> + "kill(%d, SIGCONT) failed", pid);
>> + return -1;
>> + }
>> +
>> + continue;
>> + }
>> +
>> for (i = 0; i < len; i++) {
>> if (pid == children[i]) {
>> children[i] = 0;
>
> Otherwise it looks good.
>
> I guess that there is no real chance that some of the children in
> testcases that use this function would be SIGSTOPed accidentally and
> this code will make that bug disappear...
>
Yes. I agree.
^ permalink raw reply [flat|nested] 25+ messages in thread
* [LTP] [PATCH V2 10/11] waitpid13: use the new API
2016-08-24 12:27 [LTP] waitpid: new API (part 2) V2 Stanislav Kholmanskikh
` (8 preceding siblings ...)
2016-08-24 12:27 ` [LTP] [PATCH V2 09/11] syscalls/waitpid: adapt reap_children() to test stopped children Stanislav Kholmanskikh
@ 2016-08-24 12:27 ` Stanislav Kholmanskikh
2016-08-25 12:07 ` Cyril Hrubis
2016-08-24 12:27 ` [LTP] [PATCH V2 11/11] waitpid08: test stopped children Stanislav Kholmanskikh
10 siblings, 1 reply; 25+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-24 12:27 UTC (permalink / raw)
To: ltp
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
Changes since V1:
* the part modifying waitpid_common.h is in a separate (the previous) patch
testcases/kernel/syscalls/waitpid/waitpid13.c | 401 +++----------------------
1 files changed, 50 insertions(+), 351 deletions(-)
diff --git a/testcases/kernel/syscalls/waitpid/waitpid13.c b/testcases/kernel/syscalls/waitpid/waitpid13.c
index 5f03592..13377c8 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid13.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid13.c
@@ -1,382 +1,81 @@
/*
+ * 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
-
-static int fail;
+#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 fork_kid_pid[MAXKIDS], wait_kid_pid[MAXKIDS];
- int pid;
+ pid_t pid, group;
+ int i;
+ int status;
- 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();
-
- 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_resm(TFAIL | TERRNO, "forking kid %d failed",
- kid_count);
-
- /* 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"
- "from waitpid(WNOHANG|WUNTRACED)");
- 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
+ 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, "killing child %d failed", i);
- fail = 1;
- }
- }
-
- /*
- * 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, WUNTRACED)) != -1) ||
- (errno == EINTR)) {
- if (ret_val == -1)
- continue;
-
- if (!WIFEXITED(status)) {
- if (!WIFSTOPPED(status)) {
- tst_resm(TFAIL, "Child %d is 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",
- WEXITSTATUS(status));
- fail = 1;
- }
- }
- if (kill(ret_val, SIGCONT) < 0) {
- tst_resm(TFAIL | TERRNO,
- "killing child %d failed", ret_val);
- fail = 1;
- }
- }
- found = 0;
- for (j = 0; j < kid_count; j++) {
- if (ret_val == wait_kid_pid[j]) {
- found = 1;
- break;
- }
- }
- if (!found)
- 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 = (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 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 (kid_count != (MAXKIDS / 2)) {
- tst_resm(TFAIL, "Wrong number of children waited on "
- "for pid = 0");
- tst_resm(TFAIL, "Expected %d got %d", MAXKIDS, kid_count);
- fail = 1;
- }
+ if (i == (MAXKIDS / 2))
+ SAFE_SETPGID(0, 0);
- /* Make sure can pickup children in a diff. process group */
+ pid = SAFE_FORK();
+ if (pid == 0)
+ do_exit(1);
- kid_count = 0;
- errno = 0;
- while (((ret_val = waitpid(-(group1), &status, WUNTRACED)) !=
- -1) || (errno == EINTR)) {
- if (ret_val == -1)
- continue;
- if (!WIFEXITED(status)) {
- if (!WIFSTOPPED(status)) {
- tst_resm(TFAIL, "Child %d is 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",
- WEXITSTATUS(status));
- fail = 1;
- }
- }
- if (kill(ret_val, SIGCONT) < 0) {
- tst_resm(TFAIL | TERRNO,
- "Killing child %d failed", ret_val);
- fail = 1;
- }
- }
- found = 0;
- for (j = 0; j < kid_count; j++) {
- if (ret_val == wait_kid_pid[j]) {
- found = 1;
- break;
- }
- }
- if (!found)
- 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 / 2); 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", fork_kid_pid[j]);
- 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 (kid_count != (MAXKIDS / 2)) {
- tst_resm(TFAIL, "Wrong number of children waited on "
- "for pid = 0");
- tst_resm(TFAIL, "Expected %d got %d", MAXKIDS, kid_count);
- fail = 1;
- }
-
- /*
- * 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", ret_val);
- fail = 1;
- }
-
- if (errno != ECHILD) {
- tst_resm(TFAIL, "Expected ECHILD from waitpid(WUNTRACED)");
- fail = 1;
- }
-
- if (fail)
- tst_resm(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");
-}
+ if (TST_TRACE(waitpid_ret_test(0, &status, WNOHANG | WUNTRACED,
+ 0, 0)))
+ return;
-static void setup(void)
-{
- TEST_PAUSE;
-}
-
-static void cleanup(void)
-{
-}
+ if (TST_TRACE(waitpid_ret_test(-group, &status, WNOHANG | WUNTRACED,
+ 0, 0)))
+ return;
-static void inthandlr(void)
-{
- intintr++;
-}
+ TST_CHECKPOINT_WAKE2(0, MAXKIDS);
-static void wait_for_parent(void)
-{
- int testvar;
+ if (TST_TRACE(reap_children(0, WUNTRACED, fork_kid_pid + (MAXKIDS / 2),
+ MAXKIDS / 2)))
+ return;
- while (!intintr)
- testvar = 0;
-}
+ if (TST_TRACE(reap_children(-group, WUNTRACED, fork_kid_pid,
+ MAXKIDS / 2)))
+ return;
-static void do_exit(void)
-{
- wait_for_parent();
- kill(getpid(), SIGSTOP);
- 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 = "waitpid13",
+ .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] 25+ messages in thread* [LTP] [PATCH V2 10/11] waitpid13: use the new API
2016-08-24 12:27 ` [LTP] [PATCH V2 10/11] waitpid13: use the new API Stanislav Kholmanskikh
@ 2016-08-25 12:07 ` Cyril Hrubis
0 siblings, 0 replies; 25+ messages in thread
From: Cyril Hrubis @ 2016-08-25 12:07 UTC (permalink / raw)
To: ltp
Hi!
> + if (TST_TRACE(waitpid_ret_test(0, &status, WNOHANG | WUNTRACED,
> + 0, 0)))
> + return;
>
> -static void setup(void)
> -{
> - TEST_PAUSE;
> -}
> -
> -static void cleanup(void)
> -{
> -}
> + if (TST_TRACE(waitpid_ret_test(-group, &status, WNOHANG | WUNTRACED,
> + 0, 0)))
> + return;
>
> -static void inthandlr(void)
> -{
> - intintr++;
> -}
> + TST_CHECKPOINT_WAKE2(0, MAXKIDS);
>
> -static void wait_for_parent(void)
> -{
> - int testvar;
> + if (TST_TRACE(reap_children(0, WUNTRACED, fork_kid_pid + (MAXKIDS / 2),
> + MAXKIDS / 2)))
> + return;
>
> - while (!intintr)
> - testvar = 0;
> -}
> + if (TST_TRACE(reap_children(-group, WUNTRACED, fork_kid_pid,
> + MAXKIDS / 2)))
> + return;
Again, these are just cosmetic, but if we shorten the group to just grp
and the waitpid_ret_test to waitpid_test, all but one of these would fit
to one line.
Otherwise this looks good.
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 25+ messages in thread
* [LTP] [PATCH V2 11/11] waitpid08: test stopped children
2016-08-24 12:27 [LTP] waitpid: new API (part 2) V2 Stanislav Kholmanskikh
` (9 preceding siblings ...)
2016-08-24 12:27 ` [LTP] [PATCH V2 10/11] waitpid13: use the new API Stanislav Kholmanskikh
@ 2016-08-24 12:27 ` Stanislav Kholmanskikh
2016-08-25 12:08 ` Cyril Hrubis
10 siblings, 1 reply; 25+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-24 12:27 UTC (permalink / raw)
To: ltp
The whole purpose of WUNTRACED is to help with handling of stopped
children. Therefore, let's expand the scope of testing by making
the children stop before we call waitpid() (similarly to waitpid13).
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
No changes since V1.
testcases/kernel/syscalls/waitpid/waitpid08.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/testcases/kernel/syscalls/waitpid/waitpid08.c b/testcases/kernel/syscalls/waitpid/waitpid08.c
index 6c8d3b9..dc29e07 100644
--- a/testcases/kernel/syscalls/waitpid/waitpid08.c
+++ b/testcases/kernel/syscalls/waitpid/waitpid08.c
@@ -43,7 +43,7 @@ static void do_child_1(void)
pid = SAFE_FORK();
if (pid == 0)
- do_exit(0);
+ do_exit(1);
fork_kid_pid[i] = pid;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [LTP] [PATCH V2 11/11] waitpid08: test stopped children
2016-08-24 12:27 ` [LTP] [PATCH V2 11/11] waitpid08: test stopped children Stanislav Kholmanskikh
@ 2016-08-25 12:08 ` Cyril Hrubis
2016-08-26 9:06 ` Stanislav Kholmanskikh
0 siblings, 1 reply; 25+ messages in thread
From: Cyril Hrubis @ 2016-08-25 12:08 UTC (permalink / raw)
To: ltp
Hi!
The rest of the patches, including this one, looks good.
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 25+ messages in thread
* [LTP] [PATCH V2 11/11] waitpid08: test stopped children
2016-08-25 12:08 ` Cyril Hrubis
@ 2016-08-26 9:06 ` Stanislav Kholmanskikh
0 siblings, 0 replies; 25+ messages in thread
From: Stanislav Kholmanskikh @ 2016-08-26 9:06 UTC (permalink / raw)
To: ltp
Hi,
On 08/25/2016 03:08 PM, Cyril Hrubis wrote:
> Hi!
> The rest of the patches, including this one, looks good.
>
I updated the patches and addressed all of your comments, except
renaming 'waitpid_ret_test()' and 'group', and pushed the series. As a
result, I have +1 of two-line expressions which could be fit into one
line. I think it's acceptable though...
Thank you very much for your review!
^ permalink raw reply [flat|nested] 25+ messages in thread