1e701e381faac8977f472b881d426335b869998dcLucas De Marchi/*
2e6b0e49b4ea7937a98b16f23d621244ee1a3e588Lucas De Marchi * Copyright (C) 2012-2013  ProFUSION embedded systems
3e701e381faac8977f472b881d426335b869998dcLucas De Marchi *
4e1b1ab24ab7b690343dbddd8087b17f6d722327cLucas De Marchi * This program is free software; you can redistribute it and/or
5e1b1ab24ab7b690343dbddd8087b17f6d722327cLucas De Marchi * modify it under the terms of the GNU Lesser General Public
6e1b1ab24ab7b690343dbddd8087b17f6d722327cLucas De Marchi * License as published by the Free Software Foundation; either
7e1b1ab24ab7b690343dbddd8087b17f6d722327cLucas De Marchi * version 2.1 of the License, or (at your option) any later version.
8e701e381faac8977f472b881d426335b869998dcLucas De Marchi *
9e701e381faac8977f472b881d426335b869998dcLucas De Marchi * This program is distributed in the hope that it will be useful,
10e701e381faac8977f472b881d426335b869998dcLucas De Marchi * but WITHOUT ANY WARRANTY; without even the implied warranty of
11e1b1ab24ab7b690343dbddd8087b17f6d722327cLucas De Marchi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12e1b1ab24ab7b690343dbddd8087b17f6d722327cLucas De Marchi * Lesser General Public License for more details.
13e701e381faac8977f472b881d426335b869998dcLucas De Marchi *
14e1b1ab24ab7b690343dbddd8087b17f6d722327cLucas De Marchi * You should have received a copy of the GNU Lesser General Public
15dea2dfee9b301da84dbb09cf510b8ebf2ef28fffLucas De Marchi * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16e701e381faac8977f472b881d426335b869998dcLucas De Marchi */
17e701e381faac8977f472b881d426335b869998dcLucas De Marchi
18c2e4286bb98c6bec77575ac0c6f862e7ddf6394fLucas De Marchi#include <dirent.h>
1980f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#include <errno.h>
2080f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#include <fcntl.h>
2180f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#include <getopt.h>
2280f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#include <limits.h>
2380f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#include <stdarg.h>
24c2e4286bb98c6bec77575ac0c6f862e7ddf6394fLucas De Marchi#include <stdio.h>
2580f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#include <stdlib.h>
2680f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#include <string.h>
27b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi#include <time.h>
2880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#include <unistd.h>
293dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi#include <sys/epoll.h>
3080f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#include <sys/prctl.h>
310de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi#include <sys/stat.h>
3280f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#include <sys/wait.h>
3380f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
3496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi#include <shared/util.h>
3596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi
3680f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi#include "testsuite.h"
3780f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
3851b1d1ab28b594ab1369fe411a6be3bce40da51cLucas De Marchistatic const char *ANSI_HIGHLIGHT_GREEN_ON = "\x1B[1;32m";
3951b1d1ab28b594ab1369fe411a6be3bce40da51cLucas De Marchistatic const char *ANSI_HIGHLIGHT_RED_ON =  "\x1B[1;31m";
4051b1d1ab28b594ab1369fe411a6be3bce40da51cLucas De Marchistatic const char *ANSI_HIGHLIGHT_OFF = "\x1B[0m";
4151b1d1ab28b594ab1369fe411a6be3bce40da51cLucas De Marchi
4280f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchistatic const char *progname;
43ed2df4e9845d58f46ec4405855036f25e8f72876Lucas De Marchistatic int oneshot = 0;
4480f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchistatic const char options_short[] = "lhn";
4580f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchistatic const struct option options[] = {
4680f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	{ "list", no_argument, 0, 'l' },
4780f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	{ "help", no_argument, 0, 'h' },
4880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	{ NULL, 0, 0, 0 }
4980f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi};
5080f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
51d2c2b8b500bfea8882dea0b6f0b68d8531860ea8Lucas De Marchi#define OVERRIDE_LIBDIR ABS_TOP_BUILDDIR "/testsuite/.libs/"
52d2c2b8b500bfea8882dea0b6f0b68d8531860ea8Lucas De Marchi
53395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchistruct _env_config {
54395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi	const char *key;
55395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi	const char *ldpreload;
56395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi} env_config[_TC_LAST] = {
57d2c2b8b500bfea8882dea0b6f0b68d8531860ea8Lucas De Marchi	[TC_UNAME_R] = { S_TC_UNAME_R, OVERRIDE_LIBDIR  "uname.so" },
58d2c2b8b500bfea8882dea0b6f0b68d8531860ea8Lucas De Marchi	[TC_ROOTFS] = { S_TC_ROOTFS, OVERRIDE_LIBDIR "path.so" },
59d2c2b8b500bfea8882dea0b6f0b68d8531860ea8Lucas De Marchi	[TC_INIT_MODULE_RETCODES] = { S_TC_INIT_MODULE_RETCODES, OVERRIDE_LIBDIR "init_module.so" },
60f6ef5d6b5fa47ab5fa9c9275eaa38916b92ca5a4Lucas De Marchi	[TC_DELETE_MODULE_RETCODES] = { S_TC_DELETE_MODULE_RETCODES, OVERRIDE_LIBDIR "delete_module.so" },
61395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi};
62395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi
63b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi#define USEC_PER_SEC  1000000ULL
64b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi#define USEC_PER_MSEC  1000ULL
65b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi#define TEST_TIMEOUT_USEC 2 * USEC_PER_SEC
66b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchistatic unsigned long long now_usec(void)
67b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi{
68b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi	struct timespec ts;
69b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi
70b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi	if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
71b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi		return 0;
72b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi
73b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi	return ts_usec(&ts);
74b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi}
75b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi
7680f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchistatic void help(void)
7780f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi{
7880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	const struct option *itr;
7980f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	const char *itr_short;
8080f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
8180f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	printf("Usage:\n"
8280f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	       "\t%s [options] <test>\n"
8380f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	       "Options:\n", basename(progname));
8480f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
8580f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	for (itr = options, itr_short = options_short;
8680f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi				itr->name != NULL; itr++, itr_short++)
8780f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi		printf("\t-%c, --%s\n", *itr_short, itr->name);
8880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi}
8980f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
90c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchistatic void test_list(const struct test *start, const struct test *stop)
9180f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi{
92c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi	const struct test *t;
9380f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
9480f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	printf("Available tests:\n");
95c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi	for (t = start; t < stop; t++)
96c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi		printf("\t%s, %s\n", t->name, t->description);
9780f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi}
9880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
99c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchiint test_init(const struct test *start, const struct test *stop,
100c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi	      int argc, char *const argv[])
10180f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi{
10280f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	progname = argv[0];
10380f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
10480f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	for (;;) {
10580f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi		int c, idx = 0;
10680f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi		c = getopt_long(argc, argv, options_short, options, &idx);
10780f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi		if (c == -1)
10880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi			break;
10980f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi		switch (c) {
11080f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi		case 'l':
111c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi			test_list(start, stop);
11280f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi			return 0;
11380f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi		case 'h':
11480f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi			help();
11580f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi			return 0;
11680f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi		case 'n':
11780f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi			oneshot = 1;
11880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi			break;
11980f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi		case '?':
12080f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi			return -1;
12180f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi		default:
12280f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi			ERR("unexpected getopt_long() value %c\n", c);
12380f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi			return -1;
12480f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi		}
12580f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	}
12680f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
12751b1d1ab28b594ab1369fe411a6be3bce40da51cLucas De Marchi	if (isatty(STDOUT_FILENO) == 0) {
12851b1d1ab28b594ab1369fe411a6be3bce40da51cLucas De Marchi		ANSI_HIGHLIGHT_OFF = "";
12951b1d1ab28b594ab1369fe411a6be3bce40da51cLucas De Marchi		ANSI_HIGHLIGHT_RED_ON = "";
13051b1d1ab28b594ab1369fe411a6be3bce40da51cLucas De Marchi		ANSI_HIGHLIGHT_GREEN_ON = "";
13151b1d1ab28b594ab1369fe411a6be3bce40da51cLucas De Marchi	}
13251b1d1ab28b594ab1369fe411a6be3bce40da51cLucas De Marchi
13380f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	return optind;
13480f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi}
13580f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
136c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchiconst struct test *test_find(const struct test *start,
137c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi			     const struct test *stop, const char *name)
13880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi{
139c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi	const struct test *t;
14080f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
141c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi	for (t = start; t < stop; t++) {
1425c42c5fcedb3d1ce1de62711870e691cf768f4caLucas De Marchi		if (streq(t->name, name))
143c5798fea9376958f62c4a7b253a9d8136c241040Lucas De Marchi			return t;
14480f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	}
14580f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
14680f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	return NULL;
14780f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi}
14880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
149ed2df4e9845d58f46ec4405855036f25e8f72876Lucas De Marchistatic int test_spawn_test(const struct test *t)
15080f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi{
15180f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	const char *const args[] = { progname, "-n", t->name, NULL };
15280f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
15380f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	execv(progname, (char *const *) args);
15480f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
15580f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	ERR("failed to spawn %s for %s: %m\n", progname, t->name);
15680f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	return EXIT_FAILURE;
15780f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi}
15880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
159ed2df4e9845d58f46ec4405855036f25e8f72876Lucas De Marchistatic int test_run_spawned(const struct test *t)
160ed2df4e9845d58f46ec4405855036f25e8f72876Lucas De Marchi{
161ed2df4e9845d58f46ec4405855036f25e8f72876Lucas De Marchi	int err = t->func(t);
162ed2df4e9845d58f46ec4405855036f25e8f72876Lucas De Marchi	exit(err);
163ed2df4e9845d58f46ec4405855036f25e8f72876Lucas De Marchi
164ed2df4e9845d58f46ec4405855036f25e8f72876Lucas De Marchi	return EXIT_FAILURE;
165ed2df4e9845d58f46ec4405855036f25e8f72876Lucas De Marchi}
166ed2df4e9845d58f46ec4405855036f25e8f72876Lucas De Marchi
1679e3b9d2e8cf295957ddad359abc80228a027ebf7Lucas De Marchiint test_spawn_prog(const char *prog, const char *const args[])
16880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi{
16980f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	execv(prog, (char *const *) args);
17080f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
1719e3b9d2e8cf295957ddad359abc80228a027ebf7Lucas De Marchi	ERR("failed to spawn %s\n", prog);
1729e3b9d2e8cf295957ddad359abc80228a027ebf7Lucas De Marchi	ERR("did you forget to build tools?\n");
17380f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	return EXIT_FAILURE;
17480f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi}
17580f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
176395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchistatic void test_export_environ(const struct test *t)
17780f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi{
178395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi	char *preload = NULL;
179395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi	size_t preloadlen = 0;
180395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi	size_t i;
18134db3f2d3e2438a2c173d051a8736083f63bd8c5Lucas De Marchi	const struct keyval *env;
182395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi
183395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi	unsetenv("LD_PRELOAD");
184395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi
185395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi	for (i = 0; i < _TC_LAST; i++) {
186395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi		const char *ldpreload;
187395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi		size_t ldpreloadlen;
188395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi		char *tmp;
189395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi
190395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi		if (t->config[i] == NULL)
191395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi			continue;
192395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi
193395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi		setenv(env_config[i].key, t->config[i], 1);
194395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi
195395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi		ldpreload = env_config[i].ldpreload;
196395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi		ldpreloadlen = strlen(ldpreload);
197395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi		tmp = realloc(preload, preloadlen + 2 + ldpreloadlen);
198395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi		if (tmp == NULL) {
199395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi			ERR("oom: test_export_environ()\n");
200395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi			return;
201395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi		}
202395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi		preload = tmp;
203395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi
204395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi		if (preloadlen > 0)
205395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi			preload[preloadlen++] = ' ';
206395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi		memcpy(preload + preloadlen, ldpreload, ldpreloadlen);
207395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi		preloadlen += ldpreloadlen;
208395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi		preload[preloadlen] = '\0';
209395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi	}
210395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi
211395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi	if (preload != NULL)
212395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi		setenv("LD_PRELOAD", preload, 1);
213395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi
214395478cbbbd5b68a65514ee1e41e634d3d5d62dbLucas De Marchi	free(preload);
21534db3f2d3e2438a2c173d051a8736083f63bd8c5Lucas De Marchi
21634db3f2d3e2438a2c173d051a8736083f63bd8c5Lucas De Marchi	for (env = t->env_vars; env && env->key; env++)
21734db3f2d3e2438a2c173d051a8736083f63bd8c5Lucas De Marchi		setenv(env->key, env->val, 1);
21880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi}
21980f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
2203dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchistatic inline int test_run_child(const struct test *t, int fdout[2],
221ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi						int fderr[2], int fdmonitor[2])
22280f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi{
22345481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi	/* kill child if parent dies */
22445481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi	prctl(PR_SET_PDEATHSIG, SIGTERM);
22545481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi
22645481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi	test_export_environ(t);
22745481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi
2283dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	/* Close read-fds and redirect std{out,err} to the write-fds */
229bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer	if (t->output.out != NULL) {
2303dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		close(fdout[0]);
2313dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		if (dup2(fdout[1], STDOUT_FILENO) < 0) {
232050db08c57c10cb964d337c5668c4dce309b8d41Lucas De Marchi			ERR("could not redirect stdout to pipe: %m\n");
2333dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			exit(EXIT_FAILURE);
2343dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		}
2353dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	}
2363dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
237bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer	if (t->output.err != NULL) {
2383dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		close(fderr[0]);
2393dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		if (dup2(fderr[1], STDERR_FILENO) < 0) {
240bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer			ERR("could not redirect stderr to pipe: %m\n");
2413dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			exit(EXIT_FAILURE);
2423dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		}
2433dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	}
2443dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
245ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi	close(fdmonitor[0]);
246ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi
2470de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi	if (t->config[TC_ROOTFS] != NULL) {
2480de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi		const char *stamp = TESTSUITE_ROOTFS "../stamp-rootfs";
2490de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi		const char *rootfs = t->config[TC_ROOTFS];
2500de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi		struct stat rootfsst, stampst;
2510de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi
2520de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi		if (stat(stamp, &stampst) != 0) {
2530de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi			ERR("could not stat %s\n - %m", stamp);
2540de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi			exit(EXIT_FAILURE);
2550de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi		}
2560de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi
2570de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi		if (stat(rootfs, &rootfsst) != 0) {
2580de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi			ERR("could not stat %s\n - %m", rootfs);
2590de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi			exit(EXIT_FAILURE);
2600de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi		}
2610de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi
2620de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi		if (stat_mstamp(&rootfsst) > stat_mstamp(&stampst)) {
2630de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi			ERR("rootfs %s is dirty, please run 'make rootfs' before runnning this test\n",
2640de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi								rootfs);
2650de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi			exit(EXIT_FAILURE);
2660de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi		}
2670de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi	}
2680de690c96c15bdbe2ea04e81092b14dc8b3cfd86Lucas De Marchi
26945481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi	if (t->need_spawn)
27045481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi		return test_spawn_test(t);
27145481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi	else
27245481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi		return test_run_spawned(t);
27345481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi}
27445481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi
27503a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchistatic int check_activity(int fd, bool activity,  const char *path,
27603a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi			  const char *stream)
27703a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi{
27803a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi	struct stat st;
27903a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi
28003a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi	/* not monitoring or monitoring and it has activity */
28103a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi	if (fd < 0 || activity)
28203a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi		return 0;
28303a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi
28403a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi	/* monitoring, there was no activity and size matches */
28503a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi	if (stat(path, &st) == 0 && st.st_size == 0)
28603a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi		return 0;
28703a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi
28803a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi	ERR("Expecting output on %s, but test didn't produce any\n", stream);
28903a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi
29003a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi	return -1;
29103a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi}
29203a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi
2933dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchistatic inline bool test_run_parent_check_outputs(const struct test *t,
294b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi			int fdout, int fderr, int fdmonitor, pid_t child)
2953dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi{
296ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi	struct epoll_event ep_outpipe, ep_errpipe, ep_monitor;
2973dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	int err, fd_ep, fd_matchout = -1, fd_matcherr = -1;
29803a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi	bool fd_activityout = false, fd_activityerr = false;
299b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi	unsigned long long end_usec, start_usec;
3003dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
3013dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	fd_ep = epoll_create1(EPOLL_CLOEXEC);
3023dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	if (fd_ep < 0) {
3033dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		ERR("could not create epoll fd: %m\n");
3043dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		return false;
3053dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	}
3063dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
307bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer	if (t->output.out != NULL) {
308bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer		fd_matchout = open(t->output.out, O_RDONLY);
3093dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		if (fd_matchout < 0) {
3103dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			err = -errno;
3113dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			ERR("could not open %s for read: %m\n",
312bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer							t->output.out);
3133dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			goto out;
3143dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		}
3153dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		memset(&ep_outpipe, 0, sizeof(struct epoll_event));
3163dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		ep_outpipe.events = EPOLLIN;
3173dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		ep_outpipe.data.ptr = &fdout;
3183dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fdout, &ep_outpipe) < 0) {
3193dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			err = -errno;
3203dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			ERR("could not add fd to epoll: %m\n");
3213dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			goto out;
3223dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		}
3233dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	} else
3243dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		fdout = -1;
3253dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
326bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer	if (t->output.err != NULL) {
327bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer		fd_matcherr = open(t->output.err, O_RDONLY);
3283dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		if (fd_matcherr < 0) {
3293dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			err = -errno;
3303dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			ERR("could not open %s for read: %m\n",
331bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer					t->output.err);
3323dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			goto out;
3333dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
3343dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		}
3353dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		memset(&ep_errpipe, 0, sizeof(struct epoll_event));
3363dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		ep_errpipe.events = EPOLLIN;
3373dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		ep_errpipe.data.ptr = &fderr;
3383dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fderr, &ep_errpipe) < 0) {
3393dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			err = -errno;
3403dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			ERR("could not add fd to epoll: %m\n");
3413dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			goto out;
3423dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		}
3433dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	} else
3443dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		fderr = -1;
3453dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
346ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi	memset(&ep_monitor, 0, sizeof(struct epoll_event));
347ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi	ep_monitor.events = EPOLLHUP;
348ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi	ep_monitor.data.ptr = &fdmonitor;
349ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi	if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fdmonitor, &ep_monitor) < 0) {
350ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi		err = -errno;
351ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi		ERR("could not add monitor fd to epoll: %m\n");
352ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi		goto out;
353ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi	}
354ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi
355b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi	start_usec = now_usec();
356b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi	end_usec = start_usec + TEST_TIMEOUT_USEC;
357b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi
358ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi	for (err = 0; fdmonitor >= 0 || fdout >= 0 || fderr >= 0;) {
359b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi		int fdcount, i, timeout;
3603dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		struct epoll_event ev[4];
361b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi		unsigned long long curr_usec = now_usec();
3623dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
363b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi		if (curr_usec > end_usec)
364b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi			break;
365b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi
366b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi		timeout = (end_usec - curr_usec) / USEC_PER_MSEC;
367b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi		fdcount = epoll_wait(fd_ep, ev, 4, timeout);
3683dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		if (fdcount < 0) {
3693dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			if (errno == EINTR)
3703dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				continue;
3713dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			err = -errno;
3723dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			ERR("could not poll: %m\n");
3733dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			goto out;
3743dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		}
3753dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
3763dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		for (i = 0;  i < fdcount; i++) {
3773dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			int *fd = ev[i].data.ptr;
3783dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
3793dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			if (ev[i].events & EPOLLIN) {
3803dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				ssize_t r, done = 0;
3813dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				char buf[4096];
3823dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				char bufmatch[4096];
3833dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				int fd_match;
3843dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
3853dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				/*
3863dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				 * compare the output from child with the one
3873dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				 * saved as correct
3883dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				 */
3893dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
3903dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				r = read(*fd, buf, sizeof(buf) - 1);
3913dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				if (r <= 0)
3923dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi					continue;
3933dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
39403a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi				if (*fd == fdout) {
3953dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi					fd_match = fd_matchout;
39603a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi					fd_activityout = true;
39703a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi				} else if (*fd == fderr) {
3983dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi					fd_match = fd_matcherr;
39903a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi					fd_activityerr = true;
40003a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi				} else {
401ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi					ERR("Unexpected activity on monitor pipe\n");
402ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi					err = -EINVAL;
403ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi					goto out;
404ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi				}
4053dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
4063dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				for (;;) {
4073dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi					int rmatch = read(fd_match,
4083dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi						bufmatch + done, r - done);
4093dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi					if (rmatch == 0)
4103dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi						break;
4113dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
4123dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi					if (rmatch < 0) {
4133dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi						if (errno == EINTR)
4143dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi							continue;
4153dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi						err = -errno;
4163dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi						ERR("could not read match fd %d\n",
4173dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi								fd_match);
4183dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi						goto out;
4193dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi					}
4203dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
4213dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi					done += rmatch;
4223dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				}
4233dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
4243dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				buf[r] = '\0';
4253dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				bufmatch[r] = '\0';
426f6dc239ed2a4d1b6abd4e52976d558cdbb730d01Lucas De Marchi
427f6dc239ed2a4d1b6abd4e52976d558cdbb730d01Lucas De Marchi				if (t->print_outputs)
428f6dc239ed2a4d1b6abd4e52976d558cdbb730d01Lucas De Marchi					printf("%s: %s\n",
429f6dc239ed2a4d1b6abd4e52976d558cdbb730d01Lucas De Marchi					       fd_match == fd_matchout ? "STDOUT:" : "STDERR:",
430f6dc239ed2a4d1b6abd4e52976d558cdbb730d01Lucas De Marchi					       buf);
431f6dc239ed2a4d1b6abd4e52976d558cdbb730d01Lucas De Marchi
4325c42c5fcedb3d1ce1de62711870e691cf768f4caLucas De Marchi				if (!streq(buf, bufmatch)) {
4333dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi					ERR("Outputs do not match on %s:\n",
43403a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi						fd_match == fd_matchout ? "STDOUT" : "STDERR");
4353dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi					ERR("correct:\n%s\n", bufmatch);
4363dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi					ERR("wrong:\n%s\n", buf);
4373dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi					err = -1;
4383dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi					goto out;
4393dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				}
4403dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			} else if (ev[i].events & EPOLLHUP) {
4413dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				if (epoll_ctl(fd_ep, EPOLL_CTL_DEL,
4423dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi							*fd, NULL) < 0) {
4433dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi					ERR("could not remove fd %d from epoll: %m\n",
4443dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi									*fd);
4453dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				}
4463dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				*fd = -1;
4473dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			}
4483dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		}
449b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi	}
4503dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
45103a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi	err = check_activity(fd_matchout, fd_activityout, t->output.out, "stdout");
45203a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi	err |= check_activity(fd_matcherr, fd_activityerr, t->output.err, "stderr");
45303a5079f620982995ac1416540ba7e3c54121f7cLucas De Marchi
454b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi	if (err == 0 && fdmonitor >= 0) {
455b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi		err = -EINVAL;
456b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi		ERR("Test '%s' timed out, killing %d\n", t->name, child);
457b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi		kill(child, SIGKILL);
4583dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	}
459b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi
4603dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchiout:
4613dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	if (fd_matchout >= 0)
4623dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		close(fd_matchout);
4633dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	if (fd_matcherr >= 0)
4643dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		close(fd_matcherr);
4653dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	if (fd_ep >= 0)
4663dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		close(fd_ep);
4673dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	return err == 0;
4683dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi}
4693dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
4703e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchistatic inline int safe_read(int fd, void *buf, size_t count)
4713e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi{
4723e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi	int r;
4733e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
4743e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi	while (1) {
4753e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		r = read(fd, buf, count);
4762ad09ccf0fc5232d9d45eb5b5b94193e64ed7ed2Lucas De Marchi		if (r == -1 && errno == EINTR)
4773e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			continue;
4783e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		break;
4793e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi	}
4803e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
4813e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi	return r;
4823e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi}
4833e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
4843e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchistatic bool check_generated_files(const struct test *t)
4853e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi{
4863e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi	const struct keyval *k;
4873e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
4883e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi	/* This is not meant to be a diff replacement, just stupidly check if
4893e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi	 * the files match. Bear in mind they can be binary files */
4903e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi	for (k = t->output.files; k && k->key; k++) {
4913e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		struct stat sta, stb;
4923e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		int fda = -1, fdb = -1;
4933e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		char bufa[4096];
4943e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		char bufb[4096];
4953e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
4963e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		fda = open(k->key, O_RDONLY);
4973e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		if (fda < 0) {
4983e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			ERR("could not open %s\n - %m\n", k->key);
4993e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			goto fail;
5003e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		}
5013e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
5023e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		fdb = open(k->val, O_RDONLY);
5033e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		if (fdb < 0) {
5043e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			ERR("could not open %s\n - %m\n", k->val);
5053e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			goto fail;
5063e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		}
5073e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
5083e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		if (fstat(fda, &sta) != 0) {
5093e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			ERR("could not fstat %d %s\n - %m\n", fda, k->key);
5103e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			goto fail;
5113e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		}
5123e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
5133e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		if (fstat(fdb, &stb) != 0) {
5143e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			ERR("could not fstat %d %s\n - %m\n", fdb, k->key);
5153e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			goto fail;
5163e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		}
5173e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
5183e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		if (sta.st_size != stb.st_size) {
5193e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			ERR("sizes do not match %s %s\n", k->key, k->val);
5203e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			goto fail;
5213e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		}
5223e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
5233e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		for (;;) {
5243e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			int r, done;
5253e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
5263e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			r = safe_read(fda, bufa, sizeof(bufa));
5273e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			if (r < 0)
5283e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi				goto fail;
5293e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
5303e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			if (r == 0)
5313e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi				/* size is already checked, go to next file */
5323e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi				goto next;
5333e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
5343e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			for (done = 0; done < r;) {
5353e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi				int r2 = safe_read(fdb, bufb + done, r - done);
5363e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
5373e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi				if (r2 <= 0)
5383e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi					goto fail;
5393e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
5403e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi				done += r2;
5413e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			}
5423e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
5433e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			if (memcmp(bufa, bufb, r) != 0)
5443e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi				goto fail;
5453e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		}
5463e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
5473e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchinext:
5483e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		close(fda);
5493e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		close(fdb);
5503e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		continue;
5513e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
5523e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchifail:
5533e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		if (fda >= 0)
5543e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			close(fda);
5553e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		if (fdb >= 0)
5563e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi			close(fdb);
5573e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
5583e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		return false;
5593e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi	}
5603e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
5613e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi	return true;
5623e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi}
5633e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
56488ac40840f0d13aaca844bb7198c252178968878Michal Marekstatic int cmp_modnames(const void *m1, const void *m2)
56588ac40840f0d13aaca844bb7198c252178968878Michal Marek{
56688ac40840f0d13aaca844bb7198c252178968878Michal Marek	const char *s1 = *(char *const *)m1;
56788ac40840f0d13aaca844bb7198c252178968878Michal Marek	const char *s2 = *(char *const *)m2;
56888ac40840f0d13aaca844bb7198c252178968878Michal Marek	int i;
56988ac40840f0d13aaca844bb7198c252178968878Michal Marek
57088ac40840f0d13aaca844bb7198c252178968878Michal Marek	for (i = 0; s1[i] || s2[i]; i++) {
57188ac40840f0d13aaca844bb7198c252178968878Michal Marek		char c1 = s1[i], c2 = s2[i];
57288ac40840f0d13aaca844bb7198c252178968878Michal Marek		if (c1 == '-')
57388ac40840f0d13aaca844bb7198c252178968878Michal Marek			c1 = '_';
57488ac40840f0d13aaca844bb7198c252178968878Michal Marek		if (c2 == '-')
57588ac40840f0d13aaca844bb7198c252178968878Michal Marek			c2 = '_';
57688ac40840f0d13aaca844bb7198c252178968878Michal Marek		if (c1 != c2)
57788ac40840f0d13aaca844bb7198c252178968878Michal Marek			return c1 - c2;
57888ac40840f0d13aaca844bb7198c252178968878Michal Marek	}
57988ac40840f0d13aaca844bb7198c252178968878Michal Marek	return 0;
58088ac40840f0d13aaca844bb7198c252178968878Michal Marek}
58188ac40840f0d13aaca844bb7198c252178968878Michal Marek
58288ac40840f0d13aaca844bb7198c252178968878Michal Marek/*
58388ac40840f0d13aaca844bb7198c252178968878Michal Marek * Store the expected module names in buf and return a list of pointers to
58488ac40840f0d13aaca844bb7198c252178968878Michal Marek * them.
58588ac40840f0d13aaca844bb7198c252178968878Michal Marek */
58688ac40840f0d13aaca844bb7198c252178968878Michal Marekstatic const char **read_expected_modules(const struct test *t,
58788ac40840f0d13aaca844bb7198c252178968878Michal Marek		char **buf, int *count)
58888ac40840f0d13aaca844bb7198c252178968878Michal Marek{
58988ac40840f0d13aaca844bb7198c252178968878Michal Marek	const char **res;
59088ac40840f0d13aaca844bb7198c252178968878Michal Marek	int len;
59188ac40840f0d13aaca844bb7198c252178968878Michal Marek	int i;
59288ac40840f0d13aaca844bb7198c252178968878Michal Marek	char *p;
59388ac40840f0d13aaca844bb7198c252178968878Michal Marek
59488ac40840f0d13aaca844bb7198c252178968878Michal Marek	if (t->modules_loaded[0] == '\0') {
59588ac40840f0d13aaca844bb7198c252178968878Michal Marek		*count = 0;
59688ac40840f0d13aaca844bb7198c252178968878Michal Marek		*buf = NULL;
59788ac40840f0d13aaca844bb7198c252178968878Michal Marek		return NULL;
59888ac40840f0d13aaca844bb7198c252178968878Michal Marek	}
59988ac40840f0d13aaca844bb7198c252178968878Michal Marek	*buf = strdup(t->modules_loaded);
60088ac40840f0d13aaca844bb7198c252178968878Michal Marek	if (!*buf) {
60188ac40840f0d13aaca844bb7198c252178968878Michal Marek		*count = -1;
60288ac40840f0d13aaca844bb7198c252178968878Michal Marek		return NULL;
60388ac40840f0d13aaca844bb7198c252178968878Michal Marek	}
60488ac40840f0d13aaca844bb7198c252178968878Michal Marek	len = 1;
60588ac40840f0d13aaca844bb7198c252178968878Michal Marek	for (p = *buf; *p; p++)
60688ac40840f0d13aaca844bb7198c252178968878Michal Marek		if (*p == ',')
60788ac40840f0d13aaca844bb7198c252178968878Michal Marek			len++;
60888ac40840f0d13aaca844bb7198c252178968878Michal Marek	res = malloc(sizeof(char *) * len);
60988ac40840f0d13aaca844bb7198c252178968878Michal Marek	if (!res) {
61088ac40840f0d13aaca844bb7198c252178968878Michal Marek		perror("malloc");
61188ac40840f0d13aaca844bb7198c252178968878Michal Marek		*count = -1;
61288ac40840f0d13aaca844bb7198c252178968878Michal Marek		free(*buf);
61388ac40840f0d13aaca844bb7198c252178968878Michal Marek		*buf = NULL;
61488ac40840f0d13aaca844bb7198c252178968878Michal Marek		return NULL;
61588ac40840f0d13aaca844bb7198c252178968878Michal Marek	}
61688ac40840f0d13aaca844bb7198c252178968878Michal Marek	i = 0;
61788ac40840f0d13aaca844bb7198c252178968878Michal Marek	res[i++] = *buf;
61888ac40840f0d13aaca844bb7198c252178968878Michal Marek	for (p = *buf; i < len; p++)
61988ac40840f0d13aaca844bb7198c252178968878Michal Marek		if (*p == ',') {
62088ac40840f0d13aaca844bb7198c252178968878Michal Marek			*p = '\0';
62188ac40840f0d13aaca844bb7198c252178968878Michal Marek			res[i++] = p + 1;
62288ac40840f0d13aaca844bb7198c252178968878Michal Marek		}
62388ac40840f0d13aaca844bb7198c252178968878Michal Marek	*count = len;
62488ac40840f0d13aaca844bb7198c252178968878Michal Marek	return res;
62588ac40840f0d13aaca844bb7198c252178968878Michal Marek}
62688ac40840f0d13aaca844bb7198c252178968878Michal Marek
62788ac40840f0d13aaca844bb7198c252178968878Michal Marekstatic char **read_loaded_modules(const struct test *t, char **buf, int *count)
62888ac40840f0d13aaca844bb7198c252178968878Michal Marek{
62988ac40840f0d13aaca844bb7198c252178968878Michal Marek	char dirname[PATH_MAX];
63088ac40840f0d13aaca844bb7198c252178968878Michal Marek	DIR *dir;
63188ac40840f0d13aaca844bb7198c252178968878Michal Marek	struct dirent *dirent;
63288ac40840f0d13aaca844bb7198c252178968878Michal Marek	int i;
63388ac40840f0d13aaca844bb7198c252178968878Michal Marek	int len = 0, bufsz;
63488ac40840f0d13aaca844bb7198c252178968878Michal Marek	char **res = NULL;
63588ac40840f0d13aaca844bb7198c252178968878Michal Marek	char *p;
63688ac40840f0d13aaca844bb7198c252178968878Michal Marek	const char *rootfs = t->config[TC_ROOTFS] ? t->config[TC_ROOTFS] : "";
63788ac40840f0d13aaca844bb7198c252178968878Michal Marek
63888ac40840f0d13aaca844bb7198c252178968878Michal Marek	/* Store the entries in /sys/module to res */
63988ac40840f0d13aaca844bb7198c252178968878Michal Marek	if (snprintf(dirname, sizeof(dirname), "%s/sys/module", rootfs)
64088ac40840f0d13aaca844bb7198c252178968878Michal Marek			>= (int)sizeof(dirname)) {
64188ac40840f0d13aaca844bb7198c252178968878Michal Marek		ERR("rootfs path too long: %s\n", rootfs);
64288ac40840f0d13aaca844bb7198c252178968878Michal Marek		*buf = NULL;
64388ac40840f0d13aaca844bb7198c252178968878Michal Marek		len = -1;
64488ac40840f0d13aaca844bb7198c252178968878Michal Marek		goto out;
64588ac40840f0d13aaca844bb7198c252178968878Michal Marek	}
64688ac40840f0d13aaca844bb7198c252178968878Michal Marek	dir = opendir(dirname);
64788ac40840f0d13aaca844bb7198c252178968878Michal Marek	/* not an error, simply return empty list */
64888ac40840f0d13aaca844bb7198c252178968878Michal Marek	if (!dir) {
64988ac40840f0d13aaca844bb7198c252178968878Michal Marek		*buf = NULL;
65088ac40840f0d13aaca844bb7198c252178968878Michal Marek		goto out;
65188ac40840f0d13aaca844bb7198c252178968878Michal Marek	}
65288ac40840f0d13aaca844bb7198c252178968878Michal Marek	bufsz = 0;
65388ac40840f0d13aaca844bb7198c252178968878Michal Marek	while ((dirent = readdir(dir))) {
65488ac40840f0d13aaca844bb7198c252178968878Michal Marek		if (dirent->d_name[0] == '.')
65588ac40840f0d13aaca844bb7198c252178968878Michal Marek			continue;
65688ac40840f0d13aaca844bb7198c252178968878Michal Marek		len++;
65788ac40840f0d13aaca844bb7198c252178968878Michal Marek		bufsz += strlen(dirent->d_name) + 1;
65888ac40840f0d13aaca844bb7198c252178968878Michal Marek	}
65988ac40840f0d13aaca844bb7198c252178968878Michal Marek	res = malloc(sizeof(char *) * len);
66088ac40840f0d13aaca844bb7198c252178968878Michal Marek	if (!res) {
66188ac40840f0d13aaca844bb7198c252178968878Michal Marek		perror("malloc");
66288ac40840f0d13aaca844bb7198c252178968878Michal Marek		len = -1;
66388ac40840f0d13aaca844bb7198c252178968878Michal Marek		goto out_dir;
66488ac40840f0d13aaca844bb7198c252178968878Michal Marek	}
66588ac40840f0d13aaca844bb7198c252178968878Michal Marek	*buf = malloc(bufsz);
66688ac40840f0d13aaca844bb7198c252178968878Michal Marek	if (!*buf) {
66788ac40840f0d13aaca844bb7198c252178968878Michal Marek		perror("malloc");
66888ac40840f0d13aaca844bb7198c252178968878Michal Marek		free(res);
66988ac40840f0d13aaca844bb7198c252178968878Michal Marek		res = NULL;
67088ac40840f0d13aaca844bb7198c252178968878Michal Marek		len = -1;
67188ac40840f0d13aaca844bb7198c252178968878Michal Marek		goto out_dir;
67288ac40840f0d13aaca844bb7198c252178968878Michal Marek	}
67388ac40840f0d13aaca844bb7198c252178968878Michal Marek	rewinddir(dir);
67488ac40840f0d13aaca844bb7198c252178968878Michal Marek	i = 0;
67588ac40840f0d13aaca844bb7198c252178968878Michal Marek	p = *buf;
67688ac40840f0d13aaca844bb7198c252178968878Michal Marek	while ((dirent = readdir(dir))) {
67788ac40840f0d13aaca844bb7198c252178968878Michal Marek		int size;
67888ac40840f0d13aaca844bb7198c252178968878Michal Marek
67988ac40840f0d13aaca844bb7198c252178968878Michal Marek		if (dirent->d_name[0] == '.')
68088ac40840f0d13aaca844bb7198c252178968878Michal Marek			continue;
68188ac40840f0d13aaca844bb7198c252178968878Michal Marek		size = strlen(dirent->d_name) + 1;
68288ac40840f0d13aaca844bb7198c252178968878Michal Marek		memcpy(p, dirent->d_name, size);
68388ac40840f0d13aaca844bb7198c252178968878Michal Marek		res[i++] = p;
68488ac40840f0d13aaca844bb7198c252178968878Michal Marek		p += size;
68588ac40840f0d13aaca844bb7198c252178968878Michal Marek	}
68688ac40840f0d13aaca844bb7198c252178968878Michal Marekout_dir:
68788ac40840f0d13aaca844bb7198c252178968878Michal Marek	closedir(dir);
68888ac40840f0d13aaca844bb7198c252178968878Michal Marekout:
68988ac40840f0d13aaca844bb7198c252178968878Michal Marek	*count = len;
69088ac40840f0d13aaca844bb7198c252178968878Michal Marek	return res;
69188ac40840f0d13aaca844bb7198c252178968878Michal Marek}
69288ac40840f0d13aaca844bb7198c252178968878Michal Marek
69388ac40840f0d13aaca844bb7198c252178968878Michal Marekstatic int check_loaded_modules(const struct test *t)
69488ac40840f0d13aaca844bb7198c252178968878Michal Marek{
69588ac40840f0d13aaca844bb7198c252178968878Michal Marek	int l1, l2, i1, i2;
69688ac40840f0d13aaca844bb7198c252178968878Michal Marek	const char **a1;
69788ac40840f0d13aaca844bb7198c252178968878Michal Marek	char **a2;
69888ac40840f0d13aaca844bb7198c252178968878Michal Marek	char *buf1, *buf2;
69988ac40840f0d13aaca844bb7198c252178968878Michal Marek	int err = false;
70088ac40840f0d13aaca844bb7198c252178968878Michal Marek
70188ac40840f0d13aaca844bb7198c252178968878Michal Marek	a1 = read_expected_modules(t, &buf1, &l1);
70288ac40840f0d13aaca844bb7198c252178968878Michal Marek	if (l1 < 0)
70388ac40840f0d13aaca844bb7198c252178968878Michal Marek		return err;
70488ac40840f0d13aaca844bb7198c252178968878Michal Marek	a2 = read_loaded_modules(t, &buf2, &l2);
70588ac40840f0d13aaca844bb7198c252178968878Michal Marek	if (l2 < 0)
70688ac40840f0d13aaca844bb7198c252178968878Michal Marek		goto out_a1;
70788ac40840f0d13aaca844bb7198c252178968878Michal Marek	qsort(a1, l1, sizeof(char *), cmp_modnames);
70888ac40840f0d13aaca844bb7198c252178968878Michal Marek	qsort(a2, l2, sizeof(char *), cmp_modnames);
70988ac40840f0d13aaca844bb7198c252178968878Michal Marek	i1 = i2 = 0;
71088ac40840f0d13aaca844bb7198c252178968878Michal Marek	err = true;
71188ac40840f0d13aaca844bb7198c252178968878Michal Marek	while (i1 < l1 || i2 < l2) {
71288ac40840f0d13aaca844bb7198c252178968878Michal Marek		int cmp;
71388ac40840f0d13aaca844bb7198c252178968878Michal Marek
71488ac40840f0d13aaca844bb7198c252178968878Michal Marek		if (i1 >= l1)
71588ac40840f0d13aaca844bb7198c252178968878Michal Marek			cmp = 1;
71688ac40840f0d13aaca844bb7198c252178968878Michal Marek		else if (i2 >= l2)
71788ac40840f0d13aaca844bb7198c252178968878Michal Marek			cmp = -1;
71888ac40840f0d13aaca844bb7198c252178968878Michal Marek		else
71988ac40840f0d13aaca844bb7198c252178968878Michal Marek			cmp = cmp_modnames(&a1[i1], &a2[i2]);
72088ac40840f0d13aaca844bb7198c252178968878Michal Marek		if (cmp == 0) {
72188ac40840f0d13aaca844bb7198c252178968878Michal Marek			i1++;
72288ac40840f0d13aaca844bb7198c252178968878Michal Marek			i2++;
72388ac40840f0d13aaca844bb7198c252178968878Michal Marek		} else if (cmp < 0) {
72488ac40840f0d13aaca844bb7198c252178968878Michal Marek			err = false;
72588ac40840f0d13aaca844bb7198c252178968878Michal Marek			ERR("module %s not loaded\n", a1[i1]);
72688ac40840f0d13aaca844bb7198c252178968878Michal Marek			i1++;
72788ac40840f0d13aaca844bb7198c252178968878Michal Marek		} else  {
72888ac40840f0d13aaca844bb7198c252178968878Michal Marek			err = false;
72988ac40840f0d13aaca844bb7198c252178968878Michal Marek			ERR("module %s is loaded but should not be \n", a2[i2]);
73088ac40840f0d13aaca844bb7198c252178968878Michal Marek			i2++;
73188ac40840f0d13aaca844bb7198c252178968878Michal Marek		}
73288ac40840f0d13aaca844bb7198c252178968878Michal Marek	}
73388ac40840f0d13aaca844bb7198c252178968878Michal Marek	free(a2);
73488ac40840f0d13aaca844bb7198c252178968878Michal Marek	free(buf2);
73588ac40840f0d13aaca844bb7198c252178968878Michal Marekout_a1:
73688ac40840f0d13aaca844bb7198c252178968878Michal Marek	free(a1);
73788ac40840f0d13aaca844bb7198c252178968878Michal Marek	free(buf1);
73888ac40840f0d13aaca844bb7198c252178968878Michal Marek	return err;
73988ac40840f0d13aaca844bb7198c252178968878Michal Marek}
74088ac40840f0d13aaca844bb7198c252178968878Michal Marek
7413dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchistatic inline int test_run_parent(const struct test *t, int fdout[2],
742b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi				int fderr[2], int fdmonitor[2], pid_t child)
74345481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi{
74445481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi	pid_t pid;
74580f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	int err;
74688ac40840f0d13aaca844bb7198c252178968878Michal Marek	bool matchout, match_modules;
7473dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
7483dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	/* Close write-fds */
749bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer	if (t->output.out != NULL)
7503dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		close(fdout[1]);
751bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer	if (t->output.err != NULL)
7523dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		close(fderr[1]);
753ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi	close(fdmonitor[1]);
7543dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
755ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi	matchout = test_run_parent_check_outputs(t, fdout[0], fderr[0],
756b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi							fdmonitor[0], child);
7573dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
7583dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	/*
7593dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	 * break pipe on the other end: either child already closed or we want
7603dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	 * to stop it
7613dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	 */
762bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer	if (t->output.out != NULL)
7633dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		close(fdout[0]);
764bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer	if (t->output.err != NULL)
7653dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		close(fderr[0]);
766ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi	close(fdmonitor[0]);
76745481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi
76845481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi	do {
76945481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi		pid = wait(&err);
77045481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi		if (pid == -1) {
77145481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi			ERR("error waitpid(): %m\n");
772f988e25c6864a9467eb53262cbd718752204f80fLucas De Marchi			err = EXIT_FAILURE;
773f988e25c6864a9467eb53262cbd718752204f80fLucas De Marchi			goto exit;
77445481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi		}
77545481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi	} while (!WIFEXITED(err) && !WIFSIGNALED(err));
77645481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi
7773dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	if (WIFEXITED(err)) {
7783dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		if (WEXITSTATUS(err) != 0)
7793dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			ERR("'%s' [%u] exited with return code %d\n",
7803dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi					t->name, pid, WEXITSTATUS(err));
7813dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		else
7823dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			LOG("'%s' [%u] exited with return code %d\n",
7833dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi					t->name, pid, WEXITSTATUS(err));
7843dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	} else if (WIFSIGNALED(err)) {
7853dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		ERR("'%s' [%u] terminated by signal %d (%s)\n", t->name, pid,
7863dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi				WTERMSIG(err), strsignal(WTERMSIG(err)));
787f988e25c6864a9467eb53262cbd718752204f80fLucas De Marchi		err = t->expected_fail ? EXIT_SUCCESS : EXIT_FAILURE;
788f988e25c6864a9467eb53262cbd718752204f80fLucas De Marchi		goto exit;
7893dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	}
7903dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
7913e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi	if (matchout)
7923e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi		matchout = check_generated_files(t);
79388ac40840f0d13aaca844bb7198c252178968878Michal Marek	if (t->modules_loaded)
79488ac40840f0d13aaca844bb7198c252178968878Michal Marek		match_modules = check_loaded_modules(t);
79588ac40840f0d13aaca844bb7198c252178968878Michal Marek	else
79688ac40840f0d13aaca844bb7198c252178968878Michal Marek		match_modules = true;
7973e451bfefbe1cb481fe9263a64e00926ebfaa229Lucas De Marchi
798fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner	if (t->expected_fail == false) {
799fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner		if (err == 0) {
80088ac40840f0d13aaca844bb7198c252178968878Michal Marek			if (matchout && match_modules)
801fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner				LOG("%sPASSED%s: %s\n",
802fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner					ANSI_HIGHLIGHT_GREEN_ON, ANSI_HIGHLIGHT_OFF,
803fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner					t->name);
804fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner			else {
80588ac40840f0d13aaca844bb7198c252178968878Michal Marek				ERR("%sFAILED%s: exit ok but %s do not match: %s\n",
806fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner					ANSI_HIGHLIGHT_RED_ON, ANSI_HIGHLIGHT_OFF,
80788ac40840f0d13aaca844bb7198c252178968878Michal Marek					matchout ? "loaded modules" : "outputs",
808fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner					t->name);
809fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner				err = EXIT_FAILURE;
810fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner			}
811f429113a473ccf3f7d98a3b3e6d6c8b6b43af5d0Lucas De Marchi		} else {
812fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner			ERR("%sFAILED%s: %s\n",
813fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner					ANSI_HIGHLIGHT_RED_ON, ANSI_HIGHLIGHT_OFF,
814fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner					t->name);
815f429113a473ccf3f7d98a3b3e6d6c8b6b43af5d0Lucas De Marchi		}
816fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner	} else {
817fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner		if (err == 0) {
818fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner			if (matchout) {
819d7293a1628ab14062cddb17d167fe094081a3221Lucas De Marchi				ERR("%sUNEXPECTED PASS%s: exit with 0: %s\n",
820658e0471b39087a9914184748eb45fa1ddfc7c9eLucas De Marchi					ANSI_HIGHLIGHT_RED_ON, ANSI_HIGHLIGHT_OFF,
821fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner					t->name);
822fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner				err = EXIT_FAILURE;
823d7293a1628ab14062cddb17d167fe094081a3221Lucas De Marchi			} else {
824d7293a1628ab14062cddb17d167fe094081a3221Lucas De Marchi				ERR("%sUNEXPECTED PASS%s: exit with 0 and outputs do not match: %s\n",
825d7293a1628ab14062cddb17d167fe094081a3221Lucas De Marchi					ANSI_HIGHLIGHT_RED_ON, ANSI_HIGHLIGHT_OFF,
826fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner					t->name);
827d7293a1628ab14062cddb17d167fe094081a3221Lucas De Marchi				err = EXIT_FAILURE;
828d7293a1628ab14062cddb17d167fe094081a3221Lucas De Marchi			}
829fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner		} else {
830d7293a1628ab14062cddb17d167fe094081a3221Lucas De Marchi			if (matchout) {
831d7293a1628ab14062cddb17d167fe094081a3221Lucas De Marchi				LOG("%sEXPECTED FAIL%s: %s\n",
832fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner					ANSI_HIGHLIGHT_GREEN_ON, ANSI_HIGHLIGHT_OFF,
833fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner					t->name);
834d7293a1628ab14062cddb17d167fe094081a3221Lucas De Marchi				err = EXIT_SUCCESS;
835d7293a1628ab14062cddb17d167fe094081a3221Lucas De Marchi			} else {
836d7293a1628ab14062cddb17d167fe094081a3221Lucas De Marchi				LOG("%sEXPECTED FAIL%s: exit with %d but outputs do not match: %s\n",
837d7293a1628ab14062cddb17d167fe094081a3221Lucas De Marchi					ANSI_HIGHLIGHT_GREEN_ON, ANSI_HIGHLIGHT_OFF,
838d7293a1628ab14062cddb17d167fe094081a3221Lucas De Marchi					WEXITSTATUS(err), t->name);
839d7293a1628ab14062cddb17d167fe094081a3221Lucas De Marchi				err = EXIT_FAILURE;
840d7293a1628ab14062cddb17d167fe094081a3221Lucas De Marchi			}
8413dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		}
842fa0046ba83bdb6d7e7a6c5285ab0082294a2ff5aDave Reisner	}
84345481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi
844f988e25c6864a9467eb53262cbd718752204f80fLucas De Marchiexit:
845f988e25c6864a9467eb53262cbd718752204f80fLucas De Marchi	LOG("------\n");
84645481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi	return err;
84745481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi}
84845481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi
849f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisnerstatic int prepend_path(const char *extra)
850f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner{
851f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner	char *oldpath, *newpath;
852f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner	int r;
853f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner
854f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner	if (extra == NULL)
855f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner		return 0;
856f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner
857f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner	oldpath = getenv("PATH");
858f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner	if (oldpath == NULL)
859f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner		return setenv("PATH", extra, 1);
860f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner
861f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner	if (asprintf(&newpath, "%s:%s", extra, oldpath) < 0) {
862050db08c57c10cb964d337c5668c4dce309b8d41Lucas De Marchi		ERR("failed to allocate memory to new PATH\n");
863f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner		return -1;
864f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner	}
865f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner
866f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner	r = setenv("PATH", newpath, 1);
867f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner	free(newpath);
868f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner
869f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner	return r;
870f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner}
871f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner
87245481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchiint test_run(const struct test *t)
87345481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi{
87480f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	pid_t pid;
8753dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	int fdout[2];
8763dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	int fderr[2];
877ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi	int fdmonitor[2];
87880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
879ed2df4e9845d58f46ec4405855036f25e8f72876Lucas De Marchi	if (t->need_spawn && oneshot)
880ed2df4e9845d58f46ec4405855036f25e8f72876Lucas De Marchi		test_run_spawned(t);
881ed2df4e9845d58f46ec4405855036f25e8f72876Lucas De Marchi
882bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer	if (t->output.out != NULL) {
8833dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		if (pipe(fdout) != 0) {
8843dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			ERR("could not create out pipe for %s\n", t->name);
8853dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			return EXIT_FAILURE;
8863dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		}
8873dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	}
8883dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
889bd4e7340bcd9f95e04a6309667ffe1a5427edcaaJohn Spencer	if (t->output.err != NULL) {
8903dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		if (pipe(fderr) != 0) {
8913dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			ERR("could not create err pipe for %s\n", t->name);
8923dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi			return EXIT_FAILURE;
8933dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi		}
8943dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi	}
8953dbb8dea5ff4fb23484b604d0c4b9c9ae77a03a5Lucas De Marchi
896ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi	if (pipe(fdmonitor) != 0) {
897ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi		ERR("could not create monitor pipe for %s\n", t->name);
898ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi		return EXIT_FAILURE;
899ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi	}
900ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi
901f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner	if (prepend_path(t->path) < 0) {
902f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner		ERR("failed to prepend '%s' to PATH\n", t->path);
903f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner		return EXIT_FAILURE;
904f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner	}
905f31d49c8b3a8ef863a6d6401b98b9e59a29ea53dDave Reisner
90680f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	LOG("running %s, in forked context\n", t->name);
90780f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
90880f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	pid = fork();
90980f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	if (pid < 0) {
91080f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi		ERR("could not fork(): %m\n");
91180f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi		LOG("FAILED: %s\n", t->name);
91280f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi		return EXIT_FAILURE;
91380f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi	}
91480f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
91545481ee28c44c66a25015b7682f355d093c3b94aLucas De Marchi	if (pid > 0)
916b8e344a6d2c9526a7476b78255185a96097f2629Lucas De Marchi		return test_run_parent(t, fdout, fderr, fdmonitor, pid);
91780f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi
918ed8e93fd92a95d63198fc96d59053b6be40e09f8Lucas De Marchi	return test_run_child(t, fdout, fderr, fdmonitor);
91980f9e02382fa9e65ec903dd53d62f949078205eeLucas De Marchi}
920