1/*-
2 * Copyright (c) 2015 Antti Kantee.  All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
14 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26/*
27 * This is the guest side of a simple test framework, which just
28 * runs a test and writes the results to a given filename.  More
29 * often than not, the filename is a virtual disk device.
30 *
31 * This code runs in the application space.
32 */
33
34#include <sys/types.h>
35
36#include <err.h>
37#include <errno.h>
38#include <fcntl.h>
39#include <stdbool.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <unistd.h>
44
45#include <rumprun/tester.h>
46
47#define INITIAL "??   0\n"
48
49static const char *trydisk[] = {
50	"/dev/ld0d",
51	"/dev/xvda",
52};
53static int logfd;
54static int logrv = 1;
55
56static void
57logexit(void)
58{
59	char buf[sizeof(INITIAL)];
60
61	snprintf(buf, sizeof(buf), "%s % 3d\n", logrv == 0 ? "OK" : "NO",logrv);
62	pwrite(logfd, buf, sizeof(INITIAL)-1, 0);
63	fflush(stdout);
64	close(logfd);
65	close(STDOUT_FILENO);
66	close(STDERR_FILENO);
67	sync();
68}
69
70int
71main(int argc, char *argv[])
72{
73	unsigned int i;
74
75	/* were we ran via the test framework? */
76	if (argc < 2 || strcmp(argv[1], "__test") != 0)
77		return rumprun_test(argc, argv);
78
79	/*
80	 * XXX: need a better way to determine disk device!
81	 */
82	for (i = 0; i < __arraycount(trydisk); i++) {
83		logfd = open(trydisk[i], O_RDWR);
84		if (logfd != -1)
85			break;
86	}
87	if (logfd == -1) {
88		err(1, "rumprun_test: unable to open data device");
89	}
90
91	if (write(logfd, INITIAL, sizeof(INITIAL)-1) != sizeof(INITIAL)-1) {
92		err(1, "rumprun_test: initial write failed\n");
93	}
94
95	if (dup2(logfd, STDOUT_FILENO) == -1)
96		err(1, "rumprun_test: dup2 to stdout");
97	if (dup2(logfd, STDERR_FILENO) == -1)
98		err(1, "rumprun_test: dup2 to stdout");
99
100	/*
101	 * Run the actual test.  This would of course be much nicer if
102	 * we had the ability to do something like dlsym(RTLD_NEXT),
103	 * but we don't for now, so let's not try about it.
104	 */
105	printf("=== FOE RUMPRUN 12345 TES-TER 54321 ===\n");
106	atexit(logexit);
107	logrv = rumprun_test(argc-1, argv+1);
108	printf("=== RUMPRUN 12345 TES-TER 54321 EOF ===\n");
109
110	exit(logrv);
111}
112