aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLucas De Marchi <lucas.de.marchi@gmail.com>2012-06-06 00:39:43 -0300
committerLucas De Marchi <lucas.de.marchi@gmail.com>2012-06-06 01:45:30 -0300
commited8e93fd92a95d63198fc96d59053b6be40e09f8 (patch)
tree0dee4df09224445596b507cdff473b7a79a0fad3
parent535c541e60aef81fbf16038c7dc7581a07d1b758 (diff)
downloadkmod-ed8e93fd92a95d63198fc96d59053b6be40e09f8.tar.gz
testsuite: create additional pipe to monitor child
-rw-r--r--testsuite/testsuite.c46
1 files changed, 34 insertions, 12 deletions
diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c
index c00746d..de1a0fa 100644
--- a/testsuite/testsuite.c
+++ b/testsuite/testsuite.c
@@ -196,7 +196,7 @@ static void test_export_environ(const struct test *t)
}
static inline int test_run_child(const struct test *t, int fdout[2],
- int fderr[2])
+ int fderr[2], int fdmonitor[2])
{
/* kill child if parent dies */
prctl(PR_SET_PDEATHSIG, SIGTERM);
@@ -220,6 +220,8 @@ static inline int test_run_child(const struct test *t, int fdout[2],
}
}
+ close(fdmonitor[0]);
+
if (t->config[TC_ROOTFS] != NULL) {
const char *stamp = TESTSUITE_ROOTFS "../stamp-rootfs";
const char *rootfs = t->config[TC_ROOTFS];
@@ -249,14 +251,11 @@ static inline int test_run_child(const struct test *t, int fdout[2],
}
static inline bool test_run_parent_check_outputs(const struct test *t,
- int fdout, int fderr)
+ int fdout, int fderr, int fdmonitor)
{
- struct epoll_event ep_outpipe, ep_errpipe;
+ struct epoll_event ep_outpipe, ep_errpipe, ep_monitor;
int err, fd_ep, fd_matchout = -1, fd_matcherr = -1;
- if (t->output.stdout == NULL && t->output.stderr == NULL)
- return true;
-
fd_ep = epoll_create1(EPOLL_CLOEXEC);
if (fd_ep < 0) {
ERR("could not create epoll fd: %m\n");
@@ -302,7 +301,16 @@ static inline bool test_run_parent_check_outputs(const struct test *t,
} else
fderr = -1;
- for (err = 0; fdout >= 0 || fderr >= 0;) {
+ memset(&ep_monitor, 0, sizeof(struct epoll_event));
+ ep_monitor.events = EPOLLHUP;
+ ep_monitor.data.ptr = &fdmonitor;
+ if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fdmonitor, &ep_monitor) < 0) {
+ err = -errno;
+ ERR("could not add monitor fd to epoll: %m\n");
+ goto out;
+ }
+
+ for (err = 0; fdmonitor >= 0 || fdout >= 0 || fderr >= 0;) {
int fdcount, i;
struct epoll_event ev[4];
@@ -335,8 +343,13 @@ static inline bool test_run_parent_check_outputs(const struct test *t,
if (*fd == fdout)
fd_match = fd_matchout;
- else
+ else if (*fd == fderr)
fd_match = fd_matcherr;
+ else {
+ ERR("Unexpected activity on monitor pipe\n");
+ err = -EINVAL;
+ goto out;
+ }
for (;;) {
int rmatch = read(fd_match,
@@ -388,7 +401,7 @@ out:
}
static inline int test_run_parent(const struct test *t, int fdout[2],
- int fderr[2])
+ int fderr[2], int fdmonitor[2])
{
pid_t pid;
int err;
@@ -399,8 +412,10 @@ static inline int test_run_parent(const struct test *t, int fdout[2],
close(fdout[1]);
if (t->output.stderr != NULL)
close(fderr[1]);
+ close(fdmonitor[1]);
- matchout = test_run_parent_check_outputs(t, fdout[0], fderr[0]);
+ matchout = test_run_parent_check_outputs(t, fdout[0], fderr[0],
+ fdmonitor[0]);
/*
* break pipe on the other end: either child already closed or we want
@@ -410,6 +425,7 @@ static inline int test_run_parent(const struct test *t, int fdout[2],
close(fdout[0]);
if (t->output.stderr != NULL)
close(fderr[0]);
+ close(fdmonitor[0]);
do {
pid = wait(&err);
@@ -497,6 +513,7 @@ int test_run(const struct test *t)
pid_t pid;
int fdout[2];
int fderr[2];
+ int fdmonitor[2];
if (t->need_spawn && oneshot)
test_run_spawned(t);
@@ -515,6 +532,11 @@ int test_run(const struct test *t)
}
}
+ if (pipe(fdmonitor) != 0) {
+ ERR("could not create monitor pipe for %s\n", t->name);
+ return EXIT_FAILURE;
+ }
+
if (prepend_path(t->path) < 0) {
ERR("failed to prepend '%s' to PATH\n", t->path);
return EXIT_FAILURE;
@@ -530,7 +552,7 @@ int test_run(const struct test *t)
}
if (pid > 0)
- return test_run_parent(t, fdout, fderr);
+ return test_run_parent(t, fdout, fderr, fdmonitor);
- return test_run_child(t, fdout, fderr);
+ return test_run_child(t, fdout, fderr, fdmonitor);
}