/*
 * Copyright © 2007, 2011, 2013, 2014 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 * Authors:
 *    Eric Anholt <eric@anholt.net>
 *    Daniel Vetter <daniel.vetter@ffwll.ch>
 *
 */

#ifndef ANDROID
#define _GNU_SOURCE
#else
#include <libgen.h>
#endif
#include <stdio.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <string.h>
#include <sys/mman.h>
#include <signal.h>
#include <pciaccess.h>
#include <getopt.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#ifdef __linux__
#include <sys/syscall.h>
#endif
#include <pthread.h>
#include <sys/utsname.h>
#include <termios.h>
#include <errno.h>
#include <time.h>
#include <ctype.h>
#include <limits.h>
#include <locale.h>

#include "drmtest.h"
#include "intel_chipset.h"
#include "intel_io.h"
#include "igt_debugfs.h"
#include "version.h"
#include "config.h"

#include "igt_core.h"
#include "igt_aux.h"

#ifdef HAVE_LIBGEN_H
#include <libgen.h>   /* for basename() on Solaris */
#endif

/**
 * SECTION:igt_core
 * @short_description: Core i-g-t testing support
 * @title: Core
 * @include: igt.h
 *
 * This library implements the core of the i-g-t test support infrastructure.
 * Main features are the subtest enumeration, cmdline option parsing helpers for
 * subtest handling and various helpers to structure testcases with subtests and
 * handle subtest test results.
 *
 * Auxiliary code provides exit handlers, support for forked processes with test
 * result propagation. Other generally useful functionality includes optional
 * structure logging infrastructure and some support code for running reduced
 * test set on in simulated hardware environments.
 *
 * When writing tests with subtests it is extremely important that nothing
 * interferes with the subtest enumeration. In i-g-t subtests are enumerated at
 * runtime, which allows powerful testcase enumeration. But it makes subtest
 * enumeration a bit more tricky since the test code needs to be careful to
 * never run any code which might fail (like trying to do privileged operations
 * or opening device driver nodes).
 *
 * To allow this i-g-t provides #igt_fixture code blocks for setup code outside
 * of subtests and automatically skips the subtest code blocks themselves. For
 * special cases igt_only_list_subtests() is also provided.
 *
 * # Magic Control Blocks
 *
 * i-g-t makes heavy use of C macros which serve as magic control blocks. They
 * work fairly well and transparently but since C doesn't have full-blown
 * closures there are caveats:
 *
 * - Asynchronous blocks which are used to spawn children internally use fork().
 *   Which means that nonsensical control flow like jumping out of the control
 *   block is possible, but it will badly confuse the i-g-t library code. And of
 *   course all caveats of a real fork() call apply, namely that file
 *   descriptors are copied, but still point at the original file. This will
 *   terminally upset the libdrm buffer manager if both parent and child keep on
 *   using the same open instance of the drm device. Usually everything related
 *   to interacting with the kernel driver must be reinitialized to avoid such
 *   issues.
 *
 * - Code blocks with magic control flow are implemented with setjmp() and
 *   longjmp(). This applies to #igt_fixture and #igt_subtest blocks and all the
 *   three variants to finish test: igt_success(), igt_skip() and igt_fail().
 *   Mostly this is of no concern, except when such a control block changes
 *   stack variables defined in the same function as the control block resides.
 *   Any store/load behaviour after a longjmp() is ill-defined for these
 *   variables. Avoid such code.
 *
 *   Quoting the man page for longjmp():
 *
 *   "The values of automatic variables are unspecified after a call to
 *   longjmp() if they meet all the following criteria:"
 *    - "they are local to the function that made the corresponding setjmp() call;
 *    - "their values are changed between the calls to setjmp() and longjmp(); and
 *    - "they are not declared as volatile."
 *
 * # Best Practices for Test Helper Libraries Design
 *
 * Kernel tests itself tend to have fairly complex logic already. It is
 * therefore paramount that helper code, both in libraries and test-private
 * functions, add as little boilerplate code to the main test logic as possible.
 * But then dense code is hard to understand without constantly consulting
 * the documentation and implementation of all the helper functions if it
 * doesn't follow some clear patterns. Hence follow these established best
 * practices:
 *
 * - Make extensive use of the implicit control flow afforded by igt_skip(),
 *   igt_fail and igt_success(). When dealing with optional kernel features
 *   combine igt_skip() with igt_fail() to skip when the kernel support isn't
 *   available but fail when anything else goes awry. void should be the most
 *   common return type in all your functions, except object constructors of
 *   course.
 *
 * - The main test logic should have no explicit control flow for failure
 *   conditions, but instead such assumptions should be written in a declarative
 *   style.  Use one of the many macros which encapsulate i-g-t's implicit
 *   control flow.  Pick the most suitable one to have as much debug output as
 *   possible without polluting the code unnecessarily. For example
 *   igt_assert_cmpint() for comparing integers or do_ioctl() for running ioctls
 *   and checking their results.  Feel free to add new ones to the library or
 *   wrap up a set of checks into a private function to further condense your
 *   test logic.
 *
 * - When adding a new feature test function which uses igt_skip() internally,
 *   use the <prefix>_require_<feature_name> naming scheme. When you
 *   instead add a feature test function which returns a boolean, because your
 *   main test logic must take different actions depending upon the feature's
 *   availability, then instead use the <prefix>_has_<feature_name>.
 *
 * - As already mentioned eschew explicit error handling logic as much as
 *   possible. If your test absolutely has to handle the error of some function
 *   the customary naming pattern is to prefix those variants with __. Try to
 *   restrict explicit error handling to leaf functions. For the main test flow
 *   simply pass the expected error condition down into your helper code, which
 *   results in tidy and declarative test logic.
 *
 * - Make your library functions as simple to use as possible. Automatically
 *   register cleanup handlers through igt_install_exit_handler(). Reduce the
 *   amount of setup boilerplate needed by using implicit singletons and lazy
 *   structure initialization and similar design patterns.
 *
 * - Don't shy away from refactoring common code, even when there are just 2-3
 *   users and even if it's not a net reduction in code. As long as it helps to
 *   remove boilerplate and makes the code more declarative the resulting
 *   clearer test flow is worth it. All i-g-t library code has been organically
 *   extracted from testcases in this fashion.
 *
 * - For general coding style issues please follow the kernel's rules laid out
 *   in
 *   [CodingStyle](https://www.kernel.org/doc/Documentation/CodingStyle).
 *
 * # Interface with Testrunners
 *
 * i-g-t testcase are all executables which should be run as root on an
 * otherwise completely idle system. The test status is reflected in the
 * exitcode. #IGT_EXIT_SUCCESS means "success", #IGT_EXIT_SKIP "skip",
 * #IGT_EXIT_TIMEOUT that some operation "timed out".  All other exit codes
 * encode a failed test result, including any abnormal termination of the test
 * (e.g. by SIGKILL).
 *
 * On top of that tests may report unexpected results and minor issues to
 * stderr. If stderr is non-empty the test result should be treated as "warn".
 *
 * The test lists are generated at build time. Simple testcases are listed in
 * tests/single-tests.txt and tests with subtests are listed in
 * tests/multi-tests.txt. When running tests with subtest from a test runner it
 * is recommend to run each subtest individually, since otherwise the return
 * code will only reflect the overall result.
 *
 * To do that obtain the lists of subtests with "--list-subtests", which can be
 * run as non-root and doesn't require the i915 driver to be loaded (or any
 * intel gpu to be present). Then individual subtests can be run with
 * "--run-subtest". Usage help for tests with subtests can be obtained with the
 * "--help" command line option.
 */

static unsigned int exit_handler_count;
const char *igt_interactive_debug;

/* subtests helpers */
static bool list_subtests = false;
static char *run_single_subtest = NULL;
static bool run_single_subtest_found = false;
static const char *in_subtest = NULL;
static struct timespec subtest_time;
static bool in_fixture = false;
static bool test_with_subtests = false;
static bool in_atexit_handler = false;
static enum {
	CONT = 0, SKIP, FAIL
} skip_subtests_henceforth = CONT;

/* fork support state */
pid_t *test_children;
int num_test_children;
int test_children_sz;
bool test_child;

enum {
 OPT_LIST_SUBTESTS,
 OPT_RUN_SUBTEST,
 OPT_DESCRIPTION,
 OPT_DEBUG,
 OPT_INTERACTIVE_DEBUG,
 OPT_HELP = 'h'
};

static int igt_exitcode = IGT_EXIT_SUCCESS;
static const char *command_str;

static char* igt_log_domain_filter;
static struct {
	char *entries[256];
	uint8_t start, end;
} log_buffer;
static pthread_mutex_t log_buffer_mutex = PTHREAD_MUTEX_INITIALIZER;

const char *igt_test_name(void)
{
	return command_str;
}

static void _igt_log_buffer_append(char *line)
{
	pthread_mutex_lock(&log_buffer_mutex);

	free(log_buffer.entries[log_buffer.end]);
	log_buffer.entries[log_buffer.end] = line;
	log_buffer.end++;
	if (log_buffer.end == log_buffer.start)
		log_buffer.start++;

	pthread_mutex_unlock(&log_buffer_mutex);
}

static void _igt_log_buffer_reset(void)
{
	pthread_mutex_lock(&log_buffer_mutex);

	log_buffer.start = log_buffer.end = 0;

	pthread_mutex_unlock(&log_buffer_mutex);
}

static void _igt_log_buffer_dump(void)
{
	uint8_t i;

	if (in_subtest)
		fprintf(stderr, "Subtest %s failed.\n", in_subtest);
	else
		fprintf(stderr, "Test %s failed.\n", command_str);

	if (log_buffer.start == log_buffer.end) {
		fprintf(stderr, "No log.\n");
		return;
	}

	pthread_mutex_lock(&log_buffer_mutex);
	fprintf(stderr, "**** DEBUG ****\n");

	i = log_buffer.start;
	do {
		char *last_line = log_buffer.entries[i];
		fprintf(stderr, "%s", last_line);
		i++;
	} while (i != log_buffer.start && i != log_buffer.end);

	/* reset the buffer */
	log_buffer.start = log_buffer.end = 0;

	fprintf(stderr, "****  END  ****\n");
	pthread_mutex_unlock(&log_buffer_mutex);
}

__attribute__((format(printf, 1, 2)))
static void kmsg(const char *format, ...)
#define KERN_EMER	"<0>"
#define KERN_ALERT	"<1>"
#define KERN_CRIT	"<2>"
#define KERN_ERR	"<3>"
#define KERN_WARNING	"<4>"
#define KERN_NOTICE	"<5>"
#define KERN_INFO	"<6>"
#define KERN_DEBUG	"<7>"
{
	va_list ap;
	FILE *file;

	file = fopen("/dev/kmsg", "w");
	if (file == NULL)
		return;

	va_start(ap, format);
	vfprintf(file, format, ap);
	va_end(ap);

	fclose(file);
}

static void gettime(struct timespec *ts)
{
	memset(ts, 0, sizeof(*ts));

#ifdef CLOCK_MONOTONIC_COARSE
	if (clock_gettime(CLOCK_MONOTONIC_COARSE, ts))
#endif
		clock_gettime(CLOCK_MONOTONIC, ts);
}

bool __igt_fixture(void)
{
	assert(!in_fixture);

	if (igt_only_list_subtests())
		return false;

	if (skip_subtests_henceforth)
		return false;

	in_fixture = true;
	return true;
}

void __igt_fixture_complete(void)
{
	assert(in_fixture);

	in_fixture = false;
}

void __igt_fixture_end(void)
{
	assert(in_fixture);

	in_fixture = false;
	siglongjmp(igt_subtest_jmpbuf, 1);
}

/*
 * Some of the IGT tests put quite a lot of pressure on memory and when
 * running on Android they are sometimes killed by the Android low memory killer.
 * This seems to be due to some incompatibility between the kswapd free memory
 * targets and the way the lowmemorykiller assesses free memory.
 * The low memory killer really isn't usefull in this context and has no
 * interaction with the gpu driver that we are testing, so the following
 * function is used to disable it by modifying one of its module parameters.
 * We still have the normal linux oom killer to protect the kernel.
 * Apparently it is also possible for the lowmemorykiller to get included
 * in some linux distributions; so rather than check for Android we directly
 * check for the existence of the module parameter we want to adjust.
 *
 * In future, if we can get the lowmemorykiller to play nicely then we can
 * remove this hack.
 */
static void low_mem_killer_disable(bool disable)
{
	static const char* adj_fname="/sys/module/lowmemorykiller/parameters/adj";
	static const char no_lowmem_killer[] = "9999";
	int fd;
	struct stat buf;
	/* The following must persist across invocations */
	static char prev_adj_scores[256];
	static int adj_scores_len = 0;
	static bool is_disabled = false;

	/* capture the permissions bits for the lowmemkiller adj pseudo-file.
	 * Bail out if the stat fails; it probably means that there is no
	 * lowmemorykiller, but in any case we're doomed. */
	if (stat(adj_fname, &buf)) {
		igt_assert(errno == ENOENT);
		return;
	}

	/* make sure the file can be read/written - by default it is write-only */
	chmod(adj_fname, S_IRUSR | S_IWUSR);

	if (disable && !is_disabled) {
		/* read the current oom adj parameters for lowmemorykiller */
		fd = open(adj_fname, O_RDWR);
		igt_assert(fd != -1);
		adj_scores_len = read(fd, (void*)prev_adj_scores, 255);
		igt_assert(adj_scores_len > 0);

		/* writing 9999 to this module parameter effectively diables the
		 * low memory killer. This is not a real file, so we dont need to
		 * seek to the start or truncate it */
		igt_assert_eq(write(fd, no_lowmem_killer, sizeof(no_lowmem_killer)),
			      sizeof(no_lowmem_killer));
		close(fd);
		is_disabled = true;
	} else if (is_disabled) {
		/* just re-enstate the original settings */
		fd = open(adj_fname, O_WRONLY);
		igt_assert(fd != -1);
		igt_assert_eq(write(fd, prev_adj_scores, adj_scores_len),
			      adj_scores_len);
		close(fd);
		is_disabled = false;
	}

	/* re-enstate the file permissions */
	chmod(adj_fname, buf.st_mode);
}

bool igt_exit_called;
static void common_exit_handler(int sig)
{
	if (!igt_only_list_subtests()) {
		low_mem_killer_disable(false);
	}

	/* When not killed by a signal check that igt_exit() has been properly
	 * called. */
	assert(sig != 0 || igt_exit_called);
}

static void print_test_description(void)
{
	if (&__igt_test_description)
		printf("%s\n", __igt_test_description);
}

static void print_version(void)
{
	struct utsname uts;

	if (list_subtests)
		return;

	uname(&uts);

	fprintf(stdout, "IGT-Version: %s-%s (%s) (%s: %s %s)\n", PACKAGE_VERSION,
		IGT_GIT_SHA1, TARGET_CPU_PLATFORM,
		uts.sysname, uts.release, uts.machine);
}

static void print_usage(const char *help_str, bool output_on_stderr)
{
	FILE *f = output_on_stderr ? stderr : stdout;

	fprintf(f, "Usage: %s [OPTIONS]\n", command_str);
	fprintf(f, "  --list-subtests\n"
		   "  --run-subtest <pattern>\n"
		   "  --debug[=log-domain]\n"
		   "  --interactive-debug[=domain]\n"
		   "  --help-description\n"
		   "  --help\n");
	if (help_str)
		fprintf(f, "%s\n", help_str);
}


static void oom_adjust_for_doom(void)
{
	int fd;
	const char always_kill[] = "1000";

	fd = open("/proc/self/oom_score_adj", O_WRONLY);
	igt_assert(fd != -1);
	igt_assert(write(fd, always_kill, sizeof(always_kill)) == sizeof(always_kill));
	close(fd);

}

static int common_init(int *argc, char **argv,
		       const char *extra_short_opts,
		       struct option *extra_long_opts,
		       const char *help_str,
		       igt_opt_handler_t extra_opt_handler,
		       void *handler_data)
{
	int c, option_index = 0, i, x;
	static struct option long_options[] = {
		{"list-subtests", 0, 0, OPT_LIST_SUBTESTS},
		{"run-subtest", 1, 0, OPT_RUN_SUBTEST},
		{"help-description", 0, 0, OPT_DESCRIPTION},
		{"debug", optional_argument, 0, OPT_DEBUG},
		{"interactive-debug", optional_argument, 0, OPT_INTERACTIVE_DEBUG},
		{"help", 0, 0, OPT_HELP},
		{0, 0, 0, 0}
	};
	char *short_opts;
	const char *std_short_opts = "h";
	struct option *combined_opts;
	int extra_opt_count;
	int all_opt_count;
	int ret = 0;
	char *env = getenv("IGT_LOG_LEVEL");

	if (isatty(STDOUT_FILENO))
		setlocale(LC_ALL, "");

	if (env) {
		if (strcmp(env, "debug") == 0)
			igt_log_level = IGT_LOG_DEBUG;
		else if (strcmp(env, "info") == 0)
			igt_log_level = IGT_LOG_INFO;
		else if (strcmp(env, "warn") == 0)
			igt_log_level = IGT_LOG_WARN;
		else if (strcmp(env, "none") == 0)
			igt_log_level = IGT_LOG_NONE;
	}

	command_str = argv[0];
	if (strrchr(command_str, '/'))
		command_str = strrchr(command_str, '/') + 1;

	/* First calculate space for all passed-in extra long options */
	all_opt_count = 0;
	while (extra_long_opts && extra_long_opts[all_opt_count].name) {

		/* check for conflicts with standard long option values */
		for (i = 0; long_options[i].name; i++)
			if (extra_long_opts[all_opt_count].val == long_options[i].val)
				igt_warn("Conflicting long option values between --%s and --%s\n",
					 extra_long_opts[all_opt_count].name,
					 long_options[i].name);

		/* check for conflicts with short options */
		if (extra_long_opts[all_opt_count].val != ':'
		    && strchr(std_short_opts, extra_long_opts[all_opt_count].val)) {
			igt_warn("Conflicting long and short option values between --%s and -%s\n",
				 extra_long_opts[all_opt_count].name,
				 long_options[i].name);
		}


		all_opt_count++;
	}
	extra_opt_count = all_opt_count;

	/* check for conflicts in extra short options*/
	for (i = 0; extra_short_opts && extra_short_opts[i]; i++) {

		if (extra_short_opts[i] == ':')
			continue;

		/* check for conflicts with standard short options */
		if (strchr(std_short_opts, extra_short_opts[i]))
			igt_warn("Conflicting short option: -%c\n", std_short_opts[i]);

		/* check for conflicts with standard long option values */
		for (x = 0; long_options[x].name; x++)
			if (long_options[x].val == extra_short_opts[i])
				igt_warn("Conflicting short option and long option value: --%s and -%c\n",
					 long_options[x].name, extra_short_opts[i]);
	}

	all_opt_count += ARRAY_SIZE(long_options);

	combined_opts = malloc(all_opt_count * sizeof(*combined_opts));
	memcpy(combined_opts, extra_long_opts,
	       extra_opt_count * sizeof(*combined_opts));

	/* Copy the subtest long options (and the final NULL entry) */
	memcpy(&combined_opts[extra_opt_count], long_options,
		ARRAY_SIZE(long_options) * sizeof(*combined_opts));

	ret = asprintf(&short_opts, "%s%s",
		       extra_short_opts ? extra_short_opts : "",
		       std_short_opts);
	assert(ret >= 0);

	while ((c = getopt_long(*argc, argv, short_opts, combined_opts,
			       &option_index)) != -1) {
		switch(c) {
		case OPT_INTERACTIVE_DEBUG:
			if (optarg && strlen(optarg) > 0)
				igt_interactive_debug = strdup(optarg);
			else
				igt_interactive_debug = "all";
			break;
		case OPT_DEBUG:
			igt_log_level = IGT_LOG_DEBUG;
			if (optarg && strlen(optarg) > 0)
				igt_log_domain_filter = strdup(optarg);
			break;
		case OPT_LIST_SUBTESTS:
			if (!run_single_subtest)
				list_subtests = true;
			break;
		case OPT_RUN_SUBTEST:
			if (!list_subtests)
				run_single_subtest = strdup(optarg);
			break;
		case OPT_DESCRIPTION:
			print_test_description();
			ret = -1;
			goto out;
		case OPT_HELP:
			print_usage(help_str, false);
			ret = -1;
			goto out;
		case '?':
			print_usage(help_str, true);
			ret = -2;
			goto out;
		default:
			ret = extra_opt_handler(c, option_index, handler_data);
			if (ret)
				goto out;
		}
	}

out:
	free(short_opts);
	free(combined_opts);

	/* exit immediately if this test has no subtests and a subtest or the
	 * list of subtests has been requested */
	if (!test_with_subtests) {
		if (run_single_subtest) {
			igt_warn("Unknown subtest: %s\n", run_single_subtest);
			exit(IGT_EXIT_INVALID);
		}
		if (list_subtests)
			exit(IGT_EXIT_INVALID);
	}

	if (ret < 0)
		/* exit with no error for -h/--help */
		exit(ret == -1 ? 0 : IGT_EXIT_INVALID);

	if (!list_subtests) {
		kmsg(KERN_INFO "%s: executing\n", command_str);
		print_version();

		oom_adjust_for_doom();
		low_mem_killer_disable(true);
	}

	/* install exit handler, to ensure we clean up */
	igt_install_exit_handler(common_exit_handler);

	if (!test_with_subtests)
		gettime(&subtest_time);

	for (i = 0; (optind + i) < *argc; i++)
		argv[i + 1] = argv[optind + i];

	*argc = *argc - optind + 1;

	return ret;
}


/**
 * igt_subtest_init_parse_opts:
 * @argc: argc from the test's main()
 * @argv: argv from the test's main()
 * @extra_short_opts: getopt_long() compliant list with additional short options
 * @extra_long_opts: getopt_long() compliant list with additional long options
 * @help_str: help string for the additional options
 * @extra_opt_handler: handler for the additional options
 * @handler_data: user data given to @extra_opt_handler when invoked
 *
 * This function handles the subtest related command line options and allows an
 * arbitrary set of additional options. This is useful for tests which have
 * additional knobs to tune when run manually like the number of rounds execute
 * or the size of the allocated buffer objects.
 *
 * Tests without special needs should just use igt_subtest_init() or use
 * #igt_main directly instead of their own main() function.
 *
 * Returns: Forwards any option parsing errors from getopt_long.
 */
int igt_subtest_init_parse_opts(int *argc, char **argv,
				const char *extra_short_opts,
				struct option *extra_long_opts,
				const char *help_str,
				igt_opt_handler_t extra_opt_handler,
				void *handler_data)
{
	int ret;

	test_with_subtests = true;
	ret = common_init(argc, argv, extra_short_opts, extra_long_opts,
			  help_str, extra_opt_handler, handler_data);

	return ret;
}

enum igt_log_level igt_log_level = IGT_LOG_INFO;

/**
 * igt_simple_init_parse_opts:
 * @argc: argc from the test's main()
 * @argv: argv from the test's main()
 * @extra_short_opts: getopt_long() compliant list with additional short options
 * @extra_long_opts: getopt_long() compliant list with additional long options
 * @help_str: help string for the additional options
 * @extra_opt_handler: handler for the additional options
 * @handler_data: user data given to @extra_opt_handler when invoked
 *
 * This initializes a simple test without any support for subtests and allows
 * an arbitrary set of additional options.
 */
void igt_simple_init_parse_opts(int *argc, char **argv,
				const char *extra_short_opts,
				struct option *extra_long_opts,
				const char *help_str,
				igt_opt_handler_t extra_opt_handler,
				void *handler_data)
{
	common_init(argc, argv, extra_short_opts, extra_long_opts, help_str,
		    extra_opt_handler, handler_data);
}

/*
 * Note: Testcases which use these helpers MUST NOT output anything to stdout
 * outside of places protected by igt_run_subtest checks - the piglit
 * runner adds every line to the subtest list.
 */
bool __igt_run_subtest(const char *subtest_name)
{
	int i;

	assert(!in_subtest);
	assert(!in_fixture);
	assert(test_with_subtests);

	/* check the subtest name only contains a-z, A-Z, 0-9, '-' and '_' */
	for (i = 0; subtest_name[i] != '\0'; i++)
		if (subtest_name[i] != '_' && subtest_name[i] != '-'
		    && !isalnum(subtest_name[i])) {
			igt_critical("Invalid subtest name \"%s\".\n",
				     subtest_name);
			igt_exit();
		}

	if (list_subtests) {
		printf("%s\n", subtest_name);
		return false;
	}

	if (run_single_subtest) {
		if (strcmp(subtest_name, run_single_subtest) != 0)
			return false;
		else
			run_single_subtest_found = true;
	}

	if (skip_subtests_henceforth) {
		printf("Subtest %s: %s\n", subtest_name,
		       skip_subtests_henceforth == SKIP ?
		       "SKIP" : "FAIL");
		return false;
	}

	kmsg(KERN_INFO "%s: starting subtest %s\n", command_str, subtest_name);
	igt_debug("Starting subtest: %s\n", subtest_name);

	_igt_log_buffer_reset();

	gettime(&subtest_time);
	return (in_subtest = subtest_name);
}

/**
 * igt_subtest_name:
 *
 * Returns: The name of the currently executed subtest or NULL if called from
 * outside a subtest block.
 */
const char *igt_subtest_name(void)
{
	return in_subtest;
}

/**
 * igt_only_list_subtests:
 *
 * Returns: Returns true if only subtest should be listed and any setup code
 * must be skipped, false otherwise.
 */
bool igt_only_list_subtests(void)
{
	return list_subtests;
}

static bool skipped_one = false;
static bool succeeded_one = false;
static bool failed_one = false;

static void exit_subtest(const char *) __attribute__((noreturn));
static void exit_subtest(const char *result)
{
	struct timespec now;
	double elapsed;

	gettime(&now);
	elapsed = now.tv_sec - subtest_time.tv_sec;
	elapsed += (now.tv_nsec - subtest_time.tv_nsec) * 1e-9;

	printf("Subtest %s: %s (%.3fs)\n", in_subtest, result, elapsed);
	fflush(stdout);

	in_subtest = NULL;
	siglongjmp(igt_subtest_jmpbuf, 1);
}

/**
 * igt_skip:
 * @f: format string
 * @...: optional arguments used in the format string
 *
 * Subtest aware test skipping. The format string is printed to stderr as the
 * reason why the test skipped.
 *
 * For tests with subtests this will either bail out of the current subtest or
 * mark all subsequent subtests as SKIP (presuming some global setup code
 * failed).
 *
 * For normal tests without subtest it will directly exit.
 */
void igt_skip(const char *f, ...)
{
	va_list args;
	skipped_one = true;

	assert(!test_child);

	if (!igt_only_list_subtests()) {
		va_start(args, f);
		vprintf(f, args);
		va_end(args);
	}

	if (in_subtest) {
		exit_subtest("SKIP");
	} else if (test_with_subtests) {
		skip_subtests_henceforth = SKIP;
		assert(in_fixture);
		__igt_fixture_end();
	} else {
		igt_exitcode = IGT_EXIT_SKIP;
		igt_exit();
	}
}

void __igt_skip_check(const char *file, const int line,
		      const char *func, const char *check,
		      const char *f, ...)
{
	va_list args;
	int err = errno;
	char *err_str = NULL;

	if (err)
		igt_assert_neq(asprintf(&err_str, "Last errno: %i, %s\n", err, strerror(err)),
			       -1);

	if (f) {
		static char *buf;

		/* igt_skip never returns, so try to not leak too badly. */
		if (buf)
			free(buf);

		va_start(args, f);
		igt_assert_neq(vasprintf(&buf, f, args), -1);
		va_end(args);

		igt_skip("Test requirement not met in function %s, file %s:%i:\n"
			 "Test requirement: %s\n%s"
			 "%s",
			 func, file, line, check, buf, err_str ?: "");
	} else {
		igt_skip("Test requirement not met in function %s, file %s:%i:\n"
			 "Test requirement: %s\n"
			 "%s",
			 func, file, line, check, err_str ?: "");
	}
}

/**
 * igt_success:
 *
 * Complete a (subtest) as successful
 *
 * This bails out of a subtests and marks it as successful. For global tests it
 * it won't bail out of anything.
 */
void igt_success(void)
{
	succeeded_one = true;
	if (in_subtest)
		exit_subtest("SUCCESS");
}

/**
 * igt_fail:
 * @exitcode: exitcode
 *
 * Fail a testcase. The exitcode is used as the exit code of the test process.
 * It may not be 0 (which indicates success) or 77 (which indicates a skipped
 * test).
 *
 * For tests with subtests this will either bail out of the current subtest or
 * mark all subsequent subtests as FAIL (presuming some global setup code
 * failed).
 *
 * For normal tests without subtest it will directly exit with the given
 * exitcode.
 */
void igt_fail(int exitcode)
{
	assert(exitcode != IGT_EXIT_SUCCESS && exitcode != IGT_EXIT_SKIP);

	igt_debug_wait_for_keypress("failure");

	/* Exit immediately if the test is already exiting and igt_fail is
	 * called. This can happen if an igt_assert fails in an exit handler */
	if (in_atexit_handler)
		_exit(IGT_EXIT_FAILURE);

	if (!failed_one)
		igt_exitcode = exitcode;

	failed_one = true;

	/* Silent exit, parent will do the yelling. */
	if (test_child)
		exit(exitcode);

	_igt_log_buffer_dump();

	if (in_subtest) {
		if (exitcode == IGT_EXIT_TIMEOUT)
			exit_subtest("TIMEOUT");
		else
			exit_subtest("FAIL");
	} else {
		assert(!test_with_subtests || in_fixture);

		if (in_fixture) {
			skip_subtests_henceforth = FAIL;
			__igt_fixture_end();
		}

		igt_exit();
	}
}

static bool run_under_gdb(void)
{
	char buf[1024];

	sprintf(buf, "/proc/%d/exe", getppid());
	return (readlink (buf, buf, sizeof (buf)) != -1 &&
		strncmp(basename(buf), "gdb", 3) == 0);
}

#ifdef HAVE_LIBUNWIND
#define UNW_LOCAL_ONLY
#include <libunwind.h>

static void print_backtrace(void)
{
	unw_cursor_t cursor;
	unw_context_t uc;
	int stack_num = 0;

	printf("Stack trace:\n");

	unw_getcontext(&uc);
	unw_init_local(&cursor, &uc);
	while (unw_step(&cursor) > 0) {
		char name[255];
		unw_word_t off;

		if (unw_get_proc_name(&cursor, name, 255, &off) < 0)
			strcpy(name, "<unknown>");

		printf("  #%d [%s+0x%x]\n", stack_num++, name,
		       (unsigned int) off);
	}
}
#endif

void __igt_fail_assert(const char *domain, const char *file, const int line,
		       const char *func, const char *assertion,
		       const char *f, ...)
{
	va_list args;
	int err = errno;

	igt_log(domain, IGT_LOG_CRITICAL,
		"Test assertion failure function %s, file %s:%i:\n", func, file,
		line);
	igt_log(domain, IGT_LOG_CRITICAL, "Failed assertion: %s\n", assertion);
	if (err)
		igt_log(domain, IGT_LOG_CRITICAL, "Last errno: %i, %s\n", err,
			strerror(err));

	if (f) {
		va_start(args, f);
		igt_vlog(domain, IGT_LOG_CRITICAL, f, args);
		va_end(args);
	}

#ifdef HAVE_LIBUNWIND
	print_backtrace();
#endif

	if (run_under_gdb())
		abort();
	igt_fail(IGT_EXIT_FAILURE);
}

/**
 * igt_exit:
 *
 * exit() for both types (simple and with subtests) of i-g-t tests.
 *
 * This will exit the test with the right exit code when subtests have been
 * skipped. For normal tests it exits with a successful exit code, presuming
 * everything has worked out. For subtests it also checks that at least one
 * subtest has been run (save when only listing subtests.
 *
 * It is an error to normally exit a test calling igt_exit() - without it the
 * result reporting will be wrong. To avoid such issues it is highly recommended
 * to use #igt_main or #igt_simple_main instead of a hand-rolled main() function.
 */
void igt_exit(void)
{
	igt_exit_called = true;

	if (run_single_subtest && !run_single_subtest_found) {
		igt_warn("Unknown subtest: %s\n", run_single_subtest);
		exit(IGT_EXIT_INVALID);
	}


	if (igt_only_list_subtests())
		exit(IGT_EXIT_SUCCESS);

	kmsg(KERN_INFO "%s: exiting, ret=%d\n", command_str, igt_exitcode);
	igt_debug("Exiting with status code %d\n", igt_exitcode);

	if (!test_with_subtests) {
		struct timespec now;
		double elapsed;
		const char *result;

		gettime(&now);
		elapsed = now.tv_sec - subtest_time.tv_sec;
		elapsed += (now.tv_nsec - subtest_time.tv_nsec) * 1e-9;

		switch (igt_exitcode) {
			case IGT_EXIT_SUCCESS:
				result = "SUCCESS";
				break;
			case IGT_EXIT_TIMEOUT:
				result = "TIMEOUT";
				break;
			case IGT_EXIT_SKIP:
				result = "SKIP";
				break;
			default:
				result = "FAIL";
		}


		printf("%s (%.3fs)\n", result, elapsed);
		exit(igt_exitcode);
	}

	/* Calling this without calling one of the above is a failure */
	assert(skipped_one || succeeded_one || failed_one);

	if (failed_one)
		exit(igt_exitcode);
	else if (succeeded_one)
		exit(IGT_EXIT_SUCCESS);
	else
		exit(IGT_EXIT_SKIP);
}

/* fork support code */
static int helper_process_count;
static pid_t helper_process_pids[] =
{ -1, -1, -1, -1};

static void reset_helper_process_list(void)
{
	for (int i = 0; i < ARRAY_SIZE(helper_process_pids); i++)
		helper_process_pids[i] = -1;
	helper_process_count = 0;
}

static int __waitpid(pid_t pid)
{
	int status = -1;
	while (waitpid(pid, &status, 0) == -1 &&
	       errno == EINTR)
		;

	return status;
}

static void fork_helper_exit_handler(int sig)
{
	/* Inside a signal handler, play safe */
	for (int i = 0; i < ARRAY_SIZE(helper_process_pids); i++) {
		pid_t pid = helper_process_pids[i];
		if (pid != -1) {
			kill(pid, SIGTERM);
			__waitpid(pid);
			helper_process_count--;
		}
	}

	assert(helper_process_count == 0);
}

bool __igt_fork_helper(struct igt_helper_process *proc)
{
	pid_t pid;
	int id;
	int tmp_count;

	assert(!proc->running);
	assert(helper_process_count < ARRAY_SIZE(helper_process_pids));

	for (id = 0; helper_process_pids[id] != -1; id++)
		;

	igt_install_exit_handler(fork_helper_exit_handler);

	/*
	 * Avoid races when the parent stops the child before the setup code
	 * had a chance to run. This happens e.g. when skipping tests wrapped in
	 * the signal helper.
	 */
	tmp_count = exit_handler_count;
	exit_handler_count = 0;

	/* ensure any buffers are flushed before fork */
	fflush(NULL);

	switch (pid = fork()) {
	case -1:
		exit_handler_count = tmp_count;
		igt_assert(0);
	case 0:
		reset_helper_process_list();
		oom_adjust_for_doom();

		return true;
	default:
		exit_handler_count = tmp_count;
		proc->running = true;
		proc->pid = pid;
		proc->id = id;
		helper_process_pids[id] = pid;
		helper_process_count++;

		return false;
	}

}

/**
 * igt_wait_helper:
 * @proc: #igt_helper_process structure
 *
 * Joins a helper process. It is an error to call this on a helper process which
 * hasn't been spawned yet.
 */
int igt_wait_helper(struct igt_helper_process *proc)
{
	int status;

	assert(proc->running);

	status = __waitpid(proc->pid);

	proc->running = false;

	helper_process_pids[proc->id] = -1;
	helper_process_count--;

	return status;
}

/**
 * igt_stop_helper:
 * @proc: #igt_helper_process structure
 *
 * Terminates a helper process. It is an error to call this on a helper process
 * which hasn't been spawned yet.
 */
void igt_stop_helper(struct igt_helper_process *proc)
{
	int status;

	/* failure here means the pid is already dead and so waiting is safe */
	kill(proc->pid, proc->use_SIGKILL ? SIGKILL : SIGTERM);

	status = igt_wait_helper(proc);
	assert(WIFSIGNALED(status) &&
	       WTERMSIG(status) == (proc->use_SIGKILL ? SIGKILL : SIGTERM));
}

static void children_exit_handler(int sig)
{
	int status;

	/* The exit handler can be called from a fatal signal, so play safe */
	while (num_test_children-- && wait(&status))
		;
}

bool __igt_fork(void)
{
	assert(!test_with_subtests || in_subtest);
	assert(!test_child);

	igt_install_exit_handler(children_exit_handler);

	if (num_test_children >= test_children_sz) {
		if (!test_children_sz)
			test_children_sz = 4;
		else
			test_children_sz *= 2;

		test_children = realloc(test_children,
					sizeof(pid_t)*test_children_sz);
		igt_assert(test_children);
	}

	/* ensure any buffers are flushed before fork */
	fflush(NULL);

	switch (test_children[num_test_children++] = fork()) {
	case -1:
		igt_assert(0);
	case 0:
		test_child = true;
		exit_handler_count = 0;
		reset_helper_process_list();
		oom_adjust_for_doom();

		return true;
	default:
		return false;
	}

}

/**
 * igt_waitchildren:
 *
 * Wait for all children forked with igt_fork.
 *
 * The magic here is that exit codes from children will be correctly propagated
 * to the main thread, including the relevant exit code if a child thread failed.
 * Of course if multiple children failed with different exit codes the resulting
 * exit code will be non-deterministic.
 *
 * Note that igt_skip() will not be forwarded, feature tests need to be done
 * before spawning threads with igt_fork().
 */
void igt_waitchildren(void)
{
	int err = 0;
	int count;

	assert(!test_child);

	count = 0;
	while (count < num_test_children) {
		int status = -1;
		pid_t pid;
		int c;

		pid = wait(&status);
		if (pid == -1)
			continue;

		for (c = 0; c < num_test_children; c++)
			if (pid == test_children[c])
				break;
		if (c == num_test_children)
			continue;

		if (err == 0 && status != 0) {
			if (WIFEXITED(status)) {
				printf("child %i failed with exit status %i\n",
				       c, WEXITSTATUS(status));
				err = WEXITSTATUS(status);
			} else if (WIFSIGNALED(status)) {
				printf("child %i died with signal %i, %s\n",
				       c, WTERMSIG(status),
				       strsignal(WTERMSIG(status)));
				err = 128 + WTERMSIG(status);
			} else {
				printf("Unhandled failure [%d] in child %i\n", status, c);
				err = 256;
			}

			for (c = 0; c < num_test_children; c++)
				kill(test_children[c], SIGKILL);
		}

		count++;
	}

	num_test_children = 0;
	if (err)
		igt_fail(err);
}

/* exit handler code */
#define MAX_SIGNALS		32
#define MAX_EXIT_HANDLERS	10

#ifndef HAVE_SIGHANDLER_T
typedef void (*sighandler_t)(int);
#endif

static struct {
	sighandler_t handler;
	bool installed;
} orig_sig[MAX_SIGNALS];

static igt_exit_handler_t exit_handler_fn[MAX_EXIT_HANDLERS];
static bool exit_handler_disabled;
static sigset_t saved_sig_mask;
#define SIGDEF(x) { x, #x, sizeof(#x) - 1 }
#define SILENT(x) { x, NULL, 0 }
static const struct { int number; const char *name; size_t name_len; } handled_signals[] =
	{ SILENT(SIGINT), SILENT(SIGHUP), SILENT(SIGTERM), SILENT(SIGQUIT),
	  SILENT(SIGPIPE), SIGDEF(SIGABRT), SIGDEF(SIGSEGV), SIGDEF(SIGBUS) };
#undef SILENT
#undef SIGDEF

static int install_sig_handler(int sig_num, sighandler_t handler)
{
	orig_sig[sig_num].handler = signal(sig_num, handler);

	if (orig_sig[sig_num].handler == SIG_ERR)
		return -1;

	orig_sig[sig_num].installed = true;

	return 0;
}

static void restore_sig_handler(int sig_num)
{
	/* Just restore the default so that we properly fall over. */
	signal(sig_num, SIG_DFL);
}

static void restore_all_sig_handler(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(orig_sig); i++)
		restore_sig_handler(i);
}

static void call_exit_handlers(int sig)
{
	int i;

	if (!exit_handler_count) {
		return;
	}

	for (i = exit_handler_count - 1; i >= 0; i--)
		exit_handler_fn[i](sig);

	/* ensure we don't get called twice */
	exit_handler_count = 0;
}

static void igt_atexit_handler(void)
{
	in_atexit_handler = true;

	restore_all_sig_handler();

	if (!exit_handler_disabled)
		call_exit_handlers(0);
}

static bool crash_signal(int sig)
{
	switch (sig) {
	case SIGILL:
	case SIGBUS:
	case SIGSEGV:
		return true;
	default:
		return false;
	}
}

static void fatal_sig_handler(int sig)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(handled_signals); i++) {
		if (handled_signals[i].number != sig)
			continue;

		if (handled_signals[i].name_len) {
			igt_assert_eq(write(STDERR_FILENO, "Received signal ", 16),
                                      16);
			igt_assert_eq(write(STDERR_FILENO, handled_signals[i].name, handled_signals[i].name_len),
                                      handled_signals[i].name_len);
			igt_assert_eq(write(STDERR_FILENO, ".\n", 2), 2);
		}

		if (in_subtest && crash_signal(sig)) {
			/* Linux standard to return exit code as 128 + signal */
			if (!failed_one)
				igt_exitcode = 128 + sig;

			failed_one = true;

			exit_subtest("CRASH");
		}
		break;
	}

	restore_all_sig_handler();

	/*
	 * exit_handler_disabled is always false here, since when we set it
	 * we also block signals.
	 */
	call_exit_handlers(sig);

	{
#ifdef __linux__
	/* Workaround cached PID and TID races on glibc and Bionic libc. */
		pid_t pid = syscall(SYS_getpid);
		pid_t tid = syscall(SYS_gettid);

		syscall(SYS_tgkill, pid, tid, sig);
#else
		pthread_t tid = pthread_self();
		union sigval value = { .sival_ptr = NULL };

		pthread_sigqueue(tid, sig, value);
#endif
        }
}

/**
 * igt_install_exit_handler:
 * @fn: exit handler function
 *
 * Set a handler that will be called either when the process calls exit() or
 * <!-- -->returns from the main function, or one of the signals in
 * 'handled_signals' is raised. MAX_EXIT_HANDLERS handlers can be installed,
 * each of which will be called only once, even if a subsequent signal is
 * raised. If the exit handlers are called due to a signal, the signal will be
 * re-raised with the original signal disposition after all handlers returned.
 *
 * The handler will be passed the signal number if called due to a signal, or
 * 0 otherwise. Exit handlers can also be used from test children spawned with
 * igt_fork(), but not from within helper processes spawned with
 * igt_fork_helper(). The list of exit handlers is reset when forking to
 * avoid issues with children cleanup up the parent's state too early.
 */
void igt_install_exit_handler(igt_exit_handler_t fn)
{
	int i;

	for (i = 0; i < exit_handler_count; i++)
		if (exit_handler_fn[i] == fn)
			return;

	igt_assert(exit_handler_count < MAX_EXIT_HANDLERS);

	exit_handler_fn[exit_handler_count] = fn;
	exit_handler_count++;

	if (exit_handler_count > 1)
		return;

	for (i = 0; i < ARRAY_SIZE(handled_signals); i++) {
		if (install_sig_handler(handled_signals[i].number,
					fatal_sig_handler))
			goto err;
	}

	if (atexit(igt_atexit_handler))
		goto err;

	return;
err:
	restore_all_sig_handler();
	exit_handler_count--;

	igt_assert_f(0, "failed to install the signal handler\n");
}

/**
 * igt_disable_exit_handler:
 *
 * Temporarily disable all exit handlers. Useful for library code doing tricky
 * things.
 */
void igt_disable_exit_handler(void)
{
	sigset_t set;
	int i;

	if (exit_handler_disabled)
		return;

	sigemptyset(&set);
	for (i = 0; i < ARRAY_SIZE(handled_signals); i++)
		sigaddset(&set, handled_signals[i].number);

	if (sigprocmask(SIG_BLOCK, &set, &saved_sig_mask)) {
		perror("sigprocmask");
		return;
	}

	exit_handler_disabled = true;
}

/**
 * igt_enable_exit_handler:
 *
 * Re-enable all exit handlers temporarily disabled with
 * igt_disable_exit_handler().
 */
void igt_enable_exit_handler(void)
{
	if (!exit_handler_disabled)
		return;

	if (sigprocmask(SIG_SETMASK, &saved_sig_mask, NULL)) {
		perror("sigprocmask");
		return;
	}

	exit_handler_disabled = false;
}

/* simulation enviroment support */

/**
 * igt_run_in_simulation:
 *
 * This function can be used to select a reduced test set when running in
 * simulation environments. This i-g-t mode is selected by setting the
 * INTEL_SIMULATION environment variable to 1.
 *
 * Returns: True when run in simulation mode, false otherwise.
 */
bool igt_run_in_simulation(void)
{
	static int simulation = -1;

	if (simulation == -1)
		simulation = igt_check_boolean_env_var("INTEL_SIMULATION", false);

	return simulation;
}

/**
 * igt_skip_on_simulation:
 *
 * Skip tests when INTEL_SIMULATION environment variable is set. It uses
 * igt_skip() internally and hence is fully subtest aware.
 *
 * Note that in contrast to all other functions which use igt_skip() internally
 * it is allowed to use this outside of an #igt_fixture block in a test with
 * subtests. This is because in contrast to most other test requirements,
 * checking for simulation mode doesn't depend upon the present hardware and it
 * so makes a lot of sense to have this check in the outermost #igt_main block.
 */
void igt_skip_on_simulation(void)
{
	if (igt_only_list_subtests())
		return;

	if (!in_fixture && !in_subtest) {
		igt_fixture
			igt_require(!igt_run_in_simulation());
	} else
		igt_require(!igt_run_in_simulation());
}

/* structured logging */

/**
 * igt_log:
 * @domain: the log domain, or NULL for no domain
 * @level: #igt_log_level
 * @format: format string
 * @...: optional arguments used in the format string
 *
 * This is the generic structured logging helper function. i-g-t testcase should
 * output all normal message to stdout. Warning level message should be printed
 * to stderr and the test runner should treat this as an intermediate result
 * between SUCCESS and FAILURE.
 *
 * The log level can be set through the IGT_LOG_LEVEL environment variable with
 * values "debug", "info", "warn", "critical" and "none". By default verbose
 * debug message are disabled. "none" completely disables all output and is not
 * recommended since crucial issues only reported at the IGT_LOG_WARN level are
 * ignored.
 */
void igt_log(const char *domain, enum igt_log_level level, const char *format, ...)
{
	va_list args;

	va_start(args, format);
	igt_vlog(domain, level, format, args);
	va_end(args);
}

/**
 * igt_vlog:
 * @domain: the log domain, or NULL for no domain
 * @level: #igt_log_level
 * @format: format string
 * @args: variable arguments lists
 *
 * This is the generic logging helper function using an explicit varargs
 * structure and hence useful to implement domain-specific logging
 * functions.
 *
 * If there is no need to wrap up a vararg list in the caller it is simpler to
 * just use igt_log().
 */
void igt_vlog(const char *domain, enum igt_log_level level, const char *format, va_list args)
{
	FILE *file;
	char *line, *formatted_line;
	const char *program_name;
	const char *igt_log_level_str[] = {
		"DEBUG",
		"INFO",
		"WARNING",
		"CRITICAL",
		"NONE"
	};
	static bool line_continuation = false;

	assert(format);

#ifdef __GLIBC__
	program_name = program_invocation_short_name;
#else
	program_name = command_str;
#endif

	if (list_subtests && level <= IGT_LOG_WARN)
		return;

	if (vasprintf(&line, format, args) == -1)
		return;

	if (line_continuation) {
		formatted_line = strdup(line);
		if (!formatted_line)
			goto out;
	} else if (asprintf(&formatted_line, "(%s:%d) %s%s%s: %s", program_name,
		     getpid(), (domain) ? domain : "", (domain) ? "-" : "",
		     igt_log_level_str[level], line) == -1) {
		goto out;
	}

	line_continuation = line[strlen(line)] != '\n';

	/* append log buffer */
	_igt_log_buffer_append(formatted_line);

	/* check print log level */
	if (igt_log_level > level)
		goto out;

	/* check domain filter */
	if (igt_log_domain_filter) {
		/* if null domain and filter is not "application", return */
		if (!domain && strcmp(igt_log_domain_filter, "application"))
			goto out;
		/* else if domain and filter do not match, return */
		else if (domain && strcmp(igt_log_domain_filter, domain))
			goto out;
	}

	/* use stderr for warning messages and above */
	if (level >= IGT_LOG_WARN) {
		file = stderr;
		fflush(stdout);
	}
	else
		file = stdout;

	/* prepend all except information messages with process, domain and log
	 * level information */
	if (level != IGT_LOG_INFO)
		fwrite(formatted_line, sizeof(char), strlen(formatted_line),
		       file);
	else
		fwrite(line, sizeof(char), strlen(line), file);

out:
	free(line);
}

static const char *timeout_op;
static void igt_alarm_handler(int signal)
{
	if (timeout_op)
		igt_info("Timed out: %s\n", timeout_op);
	else
		igt_info("Timed out\n");

	/* exit with failure status */
	igt_fail(IGT_EXIT_FAILURE);
}

/**
 * igt_set_timeout:
 * @seconds: number of seconds before timeout
 * @op: Optional string to explain what operation has timed out in the debug log
 *
 * Fail a test and exit with #IGT_EXIT_FAILURE status after the specified
 * number of seconds have elapsed. If the current test has subtests and the
 * timeout occurs outside a subtest, subsequent subtests will be skipped and
 * marked as failed.
 *
 * Any previous timer is cancelled and no timeout is scheduled if @seconds is
 * zero. But for clarity the timeout set with this function should be cleared
 * with igt_reset_timeout().
 */
void igt_set_timeout(unsigned int seconds,
		     const char *op)
{
	struct sigaction sa;

	sa.sa_handler = igt_alarm_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;

	timeout_op = op;

	if (seconds == 0)
		sigaction(SIGALRM, NULL, NULL);
	else
		sigaction(SIGALRM, &sa, NULL);

	alarm(seconds);
}

/**
 * igt_reset_timeout:
 *
 * This function resets a timeout set by igt_set_timeout() and disables any
 * timer set up by the former function.
 */
void igt_reset_timeout(void)
{
	igt_set_timeout(0, NULL);
}

FILE *__igt_fopen_data(const char* igt_srcdir, const char* igt_datadir,
		       const char* filename)
{
	char path[PATH_MAX];
	FILE *fp;

	snprintf(path, sizeof(path), "%s/%s", igt_datadir, filename);
	fp = fopen(path, "r");
	if (!fp) {
		snprintf(path, sizeof(path), "%s/%s", igt_srcdir, filename);
		fp = fopen(path, "r");
	}

	if (!fp)
		igt_critical("Could not open data file \"%s\": %s", filename,
			     strerror(errno));

	return fp;
}