1 // SPDX-License-Identifier: LGPL-2.1-or-later
4 * BlueZ - Bluetooth protocol stack for Linux
6 * Copyright (C) 2012-2014 Intel Corporation. All rights reserved.
27 #include <sys/types.h>
28 #include <sys/mount.h>
29 #include <sys/param.h>
30 #include <sys/reboot.h>
32 #include "lib/bluetooth.h"
34 #include "lib/hci_lib.h"
35 #include "tools/hciattach.h"
41 #define CMDLINE_MAX 2048
43 static const char *own_binary;
44 static char **test_argv;
47 static bool run_auto = false;
48 static bool start_dbus = false;
49 static bool start_dbus_session;
50 static bool start_daemon = false;
51 static bool start_emulator = false;
52 static bool start_monitor = false;
53 static int num_devs = 0;
54 static const char *qemu_binary = NULL;
55 static const char *kernel_image = NULL;
56 static bool audio_support;
58 static const char *qemu_table[] = {
61 "/usr/bin/qemu-system-x86_64",
62 "/usr/bin/qemu-system-i386",
66 static const char *find_qemu(void)
70 for (i = 0; qemu_table[i]; i++) {
73 if (!stat(qemu_table[i], &st))
80 static const char *kernel_table[] = {
82 "arch/x86/boot/bzImage",
84 "arch/x86/boot/vmlinux",
88 static const char *find_kernel(void)
92 for (i = 0; kernel_table[i]; i++) {
95 if (!stat(kernel_table[i], &st))
96 return kernel_table[i];
102 static const struct {
104 const char *linkpath;
106 { "/proc/self/fd", "/dev/fd" },
107 { "/proc/self/fd/0", "/dev/stdin" },
108 { "/proc/self/fd/1", "/dev/stdout" },
109 { "/proc/self/fd/2", "/dev/stderr" },
113 static const struct {
119 { "sysfs", "/sys", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV },
120 { "proc", "/proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV },
121 { "devtmpfs", "/dev", "mode=0755", MS_NOSUID|MS_STRICTATIME },
122 { "devpts", "/dev/pts", "mode=0620", MS_NOSUID|MS_NOEXEC },
123 { "tmpfs", "/dev/shm", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME },
124 { "tmpfs", "/run", "mode=0755", MS_NOSUID|MS_NODEV|MS_STRICTATIME },
125 { "tmpfs", "/tmp", NULL, 0 },
126 { "debugfs", "/sys/kernel/debug", NULL, 0 },
130 static const char *config_table[] = {
131 "/var/lib/bluetooth",
138 static void prepare_sandbox(void)
142 for (i = 0; mount_table[i].fstype && mount_table[i].target; i++) {
145 if (lstat(mount_table[i].target, &st) < 0) {
146 printf("Creating %s\n", mount_table[i].target);
147 mkdir(mount_table[i].target, 0755);
150 printf("Mounting %s to %s\n", mount_table[i].fstype,
151 mount_table[i].target);
153 if (mount(mount_table[i].fstype,
154 mount_table[i].target,
155 mount_table[i].fstype,
156 mount_table[i].flags,
157 mount_table[i].options) < 0)
158 perror("Failed to mount filesystem");
161 for (i = 0; dev_table[i].target; i++) {
162 printf("Linking %s to %s\n", dev_table[i].linkpath,
163 dev_table[i].target);
165 if (symlink(dev_table[i].target, dev_table[i].linkpath) < 0)
166 perror("Failed to create device symlink");
169 printf("Creating new session group leader\n");
172 printf("Setting controlling terminal\n");
173 ioctl(STDIN_FILENO, TIOCSCTTY, 1);
175 for (i = 0; config_table[i]; i++) {
176 printf("Creating %s\n", config_table[i]);
178 if (mount("tmpfs", config_table[i], "tmpfs",
179 MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME,
181 perror("Failed to create filesystem");
185 static char *const qemu_argv[] = {
191 "-machine", "type=q35,accel=kvm:tcg",
198 "-fsdev", "local,id=fsdev-root,path=/,readonly,security_model=none,"
200 "-device", "virtio-9p-pci,fsdev=fsdev-root,mount_tag=/dev/root",
201 "-chardev", "stdio,id=con,mux=on",
202 "-serial", "chardev:con",
206 static char *const qemu_envp[] = {
211 static void check_virtualization(void)
213 #if defined(__GNUC__) && (defined(__i386__) || defined(__amd64__))
216 __asm__ __volatile__("cpuid" : "=c" (ecx) : "a" (1) : "memory");
218 if (!!(ecx & (1 << 5)))
219 printf("Found support for Virtual Machine eXtensions\n");
223 static void start_qemu(void)
225 char cwd[PATH_MAX/2], initcmd[PATH_MAX], testargs[PATH_MAX];
226 char cmdline[CMDLINE_MAX];
230 check_virtualization();
232 if (!getcwd(cwd, sizeof(cwd)))
235 if (own_binary[0] == '/')
236 snprintf(initcmd, sizeof(initcmd), "%s", own_binary);
238 snprintf(initcmd, sizeof(initcmd), "%s/%s", cwd, own_binary);
240 pos = snprintf(testargs, sizeof(testargs), "%s", test_argv[0]);
242 for (i = 1; i < test_argc; i++) {
243 int len = sizeof(testargs) - pos;
244 pos += snprintf(testargs + pos, len, " %s", test_argv[i]);
247 snprintf(cmdline, sizeof(cmdline),
248 "console=ttyS0,115200n8 earlyprintk=serial "
250 "rootflags=trans=virtio,version=9p2000.u "
251 "acpi=off pci=noacpi noapic quiet ro init=%s "
252 "bluetooth.enable_ecred=1 "
253 "TESTHOME=%s TESTDBUS=%u TESTDAEMON=%u "
254 "TESTDBUSSESSION=%u XDG_RUNTIME_DIR=/run/user/0 "
256 "TESTMONITOR=%u TESTEMULATOR=%u TESTDEVS=%d "
257 "TESTAUTO=%u TESTARGS=\'%s\'",
258 initcmd, cwd, start_dbus, start_daemon,
259 start_dbus_session, audio_support,
260 start_monitor, start_emulator, num_devs,
263 argv = alloca(sizeof(qemu_argv) +
264 (audio_support ? 4 : 0) +
265 (sizeof(char *) * (4 + (num_devs * 4))));
266 memcpy(argv, qemu_argv, sizeof(qemu_argv));
268 pos = (sizeof(qemu_argv) / sizeof(char *)) - 1;
270 /* Make sure qemu_binary is not null */
272 fprintf(stderr, "No QEMU binary is set\n");
275 argv[0] = (char *) qemu_binary;
278 char *xdg_runtime_dir, *audiodev;
280 xdg_runtime_dir = getenv("XDG_RUNTIME_DIR");
281 if (!xdg_runtime_dir) {
282 fprintf(stderr, "XDG_RUNTIME_DIR not set\n");
285 audiodev = alloca(40 + strlen(xdg_runtime_dir));
286 sprintf(audiodev, "id=audio,driver=pa,server=%s/pulse/native",
289 argv[pos++] = "-audiodev";
290 argv[pos++] = audiodev;
291 argv[pos++] = "-device";
292 argv[pos++] = "AC97,audiodev=audio";
295 argv[pos++] = "-kernel";
296 argv[pos++] = (char *) kernel_image;
297 argv[pos++] = "-append";
298 argv[pos++] = (char *) cmdline;
300 for (i = 0; i < num_devs; i++) {
301 const char *path = "/tmp/bt-server-bredr";
302 char *chrdev, *serdev;
304 chrdev = alloca(32 + strlen(path));
305 sprintf(chrdev, "socket,path=%s,id=bt%d", path, i);
308 sprintf(serdev, "pci-serial,chardev=bt%d", i);
310 argv[pos++] = "-chardev";
311 argv[pos++] = chrdev;
312 argv[pos++] = "-device";
313 argv[pos++] = serdev;
318 execve(argv[0], argv, qemu_envp);
321 static int open_serial(const char *path)
324 int fd, saved_ldisc, ldisc = N_HCI;
326 fd = open(path, O_RDWR | O_NOCTTY);
328 perror("Failed to open serial port");
332 if (tcflush(fd, TCIOFLUSH) < 0) {
333 perror("Failed to flush serial port");
338 if (ioctl(fd, TIOCGETD, &saved_ldisc) < 0) {
339 perror("Failed get serial line discipline");
344 /* Switch TTY to raw mode */
345 memset(&ti, 0, sizeof(ti));
348 ti.c_cflag |= (B115200 | CLOCAL | CREAD);
350 /* Set flow control */
351 ti.c_cflag |= CRTSCTS;
353 if (tcsetattr(fd, TCSANOW, &ti) < 0) {
354 perror("Failed to set serial port settings");
359 if (ioctl(fd, TIOCSETD, &ldisc) < 0) {
360 perror("Failed set serial line discipline");
365 printf("Switched line discipline from %d to %d\n", saved_ldisc, ldisc);
370 static int attach_proto(const char *path, unsigned int proto,
371 unsigned int mandatory_flags,
372 unsigned int optional_flags)
374 unsigned int flags = mandatory_flags | optional_flags;
377 fd = open_serial(path);
381 if (ioctl(fd, HCIUARTSETFLAGS, flags) < 0) {
382 if (errno == EINVAL) {
383 if (ioctl(fd, HCIUARTSETFLAGS, mandatory_flags) < 0) {
384 perror("Failed to set mandatory flags");
389 perror("Failed to set flags");
395 if (ioctl(fd, HCIUARTSETPROTO, proto) < 0) {
396 perror("Failed to set protocol");
401 dev_id = ioctl(fd, HCIUARTGETDEVICE);
403 perror("Failed to get device id");
408 printf("Device index %d attached\n", dev_id);
413 static void create_dbus_system_conf(void)
417 fp = fopen("/etc/dbus-1/system.conf", "we");
421 fputs("<!DOCTYPE busconfig PUBLIC "
422 "\"-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN\" "
423 "\"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd\">\n", fp);
424 fputs("<busconfig>\n", fp);
425 fputs("<type>system</type>\n", fp);
426 fputs("<listen>unix:path=/run/dbus/system_bus_socket</listen>\n", fp);
427 fputs("<policy context=\"default\">\n", fp);
428 fputs("<allow user=\"*\"/>\n", fp);
429 fputs("<allow own=\"*\"/>\n", fp);
430 fputs("<allow send_type=\"method_call\"/>\n",fp);
431 fputs("<allow send_type=\"signal\"/>\n", fp);
432 fputs("<allow send_type=\"method_return\"/>\n", fp);
433 fputs("<allow send_type=\"error\"/>\n", fp);
434 fputs("<allow receive_type=\"method_call\"/>\n",fp);
435 fputs("<allow receive_type=\"signal\"/>\n", fp);
436 fputs("<allow receive_type=\"method_return\"/>\n", fp);
437 fputs("<allow receive_type=\"error\"/>\n", fp);
438 fputs("</policy>\n", fp);
439 fputs("</busconfig>\n", fp);
443 if (symlink("/etc/dbus-1/system.conf",
444 "/usr/share/dbus-1/system.conf") < 0)
445 perror("Failed to create system.conf symlink");
447 mkdir("/run/dbus", 0755);
450 static void create_dbus_session_conf(void)
454 fp = fopen("/etc/dbus-1/session.conf", "we");
458 fputs("<!DOCTYPE busconfig PUBLIC "
459 "\"-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN\" "
460 "\"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd\">\n", fp);
461 fputs("<busconfig>\n", fp);
462 fputs("<type>session</type>\n", fp);
463 fputs("<listen>unix:path=/run/user/0/bus</listen>\n", fp);
464 fputs("<policy context=\"default\">\n", fp);
465 fputs("<allow user=\"*\"/>\n", fp);
466 fputs("<allow own=\"*\"/>\n", fp);
467 fputs("<allow send_type=\"method_call\"/>\n", fp);
468 fputs("<allow send_type=\"signal\"/>\n", fp);
469 fputs("<allow send_type=\"method_return\"/>\n", fp);
470 fputs("<allow send_type=\"error\"/>\n", fp);
471 fputs("<allow receive_type=\"method_call\"/>\n", fp);
472 fputs("<allow receive_type=\"signal\"/>\n", fp);
473 fputs("<allow receive_type=\"method_return\"/>\n", fp);
474 fputs("<allow receive_type=\"error\"/>\n", fp);
475 fputs("</policy>\n", fp);
476 fputs("</busconfig>\n", fp);
480 if (symlink("/etc/dbus-1/session.conf",
481 "/usr/share/dbus-1/session.conf") < 0)
482 perror("Failed to create session.conf symlink");
484 if (mkdir("/run/user", 0755) < 0) {
485 fprintf(stderr, "unable to create /run/user directory\n");
488 if (mkdir("/run/user/0", 0755) < 0) {
489 fprintf(stderr, "unable to create /run/user/0 directory\n");
494 static pid_t start_dbus_daemon(bool session)
496 char *argv[3], *envp[1];
499 char *bus_type = session ? "session" : "system";
500 char *socket_path = session ?
501 "/run/user/0/bus" : "/run/dbus/system_bus_socket";
503 argv[0] = "/usr/bin/dbus-daemon";
505 argv[1] = "--session";
507 argv[1] = "--system";
512 printf("Starting D-Bus %s daemon\n", bus_type);
516 perror("Failed to fork new process");
521 execve(argv[0], argv, envp);
525 printf("D-Bus %s daemon process %d created\n", bus_type, pid);
527 for (i = 0; i < 20; i++) {
530 if (!stat(socket_path, &st)) {
531 printf("Found D-Bus %s daemon socket\n", bus_type);
541 static const char *daemon_table[] = {
544 "/usr/sbin/bluetoothd",
545 "/usr/libexec/bluetooth/bluetoothd",
549 static pid_t start_bluetooth_daemon(const char *home)
551 const char *daemon = NULL;
552 char *argv[6], *envp[2];
557 if (chdir(home + 5) < 0) {
558 perror("Failed to change home directory for daemon");
562 for (i = 0; daemon_table[i]; i++) {
564 if (!stat(daemon_table[i], &st)) {
565 daemon = daemon_table[i];
571 fprintf(stderr, "Failed to locate Bluetooth daemon binary\n");
575 printf("Using Bluetooth daemon %s\n", daemon);
577 argv[0] = (char *) daemon;
578 argv[1] = "--nodetach";
582 if (!stat("src/main.conf", &st)) {
584 argv[4] = "src/main.conf";
588 envp[0] = "DBUS_SYSTEM_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket";
591 printf("Starting Bluetooth daemon\n");
595 perror("Failed to fork new process");
600 execve(argv[0], argv, envp);
604 printf("Bluetooth daemon process %d created\n", pid);
609 static const char *test_table[] = {
622 "tools/l2cap-tester",
623 "tools/rfcomm-tester",
627 "tools/ioctl-tester",
629 "tools/check-selftest",
633 static const char *monitor_table[] = {
640 static pid_t start_btmon(const char *home)
642 const char *monitor = NULL;
643 char *argv[3], *envp[2];
647 if (chdir(home + 5) < 0) {
648 perror("Failed to change home directory for monitor");
652 for (i = 0; monitor_table[i]; i++) {
655 if (!stat(monitor_table[i], &st)) {
656 monitor = monitor_table[i];
662 fprintf(stderr, "Failed to locate Monitor binary\n");
666 printf("Using Monitor %s\n", monitor);
668 argv[0] = (char *) monitor;
672 printf("Starting Monitor\n");
676 perror("Failed to fork new process");
681 execve(argv[0], argv, envp);
685 printf("Monitor process %d created\n", pid);
690 static const char *btvirt_table[] = {
697 static pid_t start_btvirt(const char *home)
699 const char *btvirt = NULL;
700 char *argv[3], *envp[2];
704 if (chdir(home + 5) < 0) {
705 perror("Failed to change home directory for daemon");
709 for (i = 0; btvirt_table[i]; i++) {
712 if (!stat(btvirt_table[i], &st)) {
713 btvirt = btvirt_table[i];
719 fprintf(stderr, "Failed to locate btvirt binary\n");
723 printf("Using %s\n", btvirt);
725 argv[0] = (char *) btvirt;
729 printf("Starting Emulator\n");
733 perror("Failed to fork new process");
738 execve(argv[0], argv, envp);
742 printf("Emulator process %d created\n", pid);
747 static void trigger_udev(void)
749 char *argv[3], *envp[1];
752 argv[0] = "/bin/udevadm";
758 printf("Triggering udev events\n");
762 perror("Failed to fork new process");
767 execve(argv[0], argv, envp);
771 printf("udev trigger process %d created\n", pid);
774 static pid_t start_udevd(void)
776 char *argv[2], *envp[1];
779 argv[0] = "/lib/systemd/systemd-udevd";
784 printf("Starting udevd daemon\n");
788 perror("Failed to fork new process");
793 execve(argv[0], argv, envp);
797 printf("udevd daemon process %d created\n", pid);
804 static void run_command(char *cmdname, char *home)
806 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
807 char *argv[10], *envp[3];
809 char *argv[9], *envp[3];
811 int pos = 0, idx = 0;
813 pid_t pid, dbus_pid, daemon_pid, monitor_pid, emulator_pid,
814 dbus_session_pid, udevd_pid;
817 perror("Invalid parameter: TESTHOME");
822 const char *node = "/dev/ttyS1";
823 unsigned int basic_flags, extra_flags;
825 printf("Attaching BR/EDR controller to %s\n", node);
827 basic_flags = (1 << HCI_UART_RESET_ON_INIT);
828 extra_flags = (1 << HCI_UART_VND_DETECT);
830 serial_fd = attach_proto(node, HCI_UART_H4, basic_flags,
836 udevd_pid = start_udevd();
841 create_dbus_system_conf();
842 dbus_pid = start_dbus_daemon(false);
846 if (start_dbus_session) {
847 create_dbus_session_conf();
848 dbus_session_pid = start_dbus_daemon(true);
850 dbus_session_pid = -1;
853 daemon_pid = start_bluetooth_daemon(home);
858 monitor_pid = start_btmon(home);
863 emulator_pid = start_btvirt(home);
869 if (chdir(home + 5) < 0) {
870 perror("Failed to change home test directory");
877 if (!test_table[idx])
880 if (!stat(test_table[idx], &st))
886 argv[0] = (char *) test_table[idx];
893 envp[pos++] = "TERM=linux";
898 printf("Running command %s\n", cmdname ? cmdname : argv[0]);
902 perror("Failed to fork new process");
908 printf("Changing into directory %s\n", home + 5);
909 if (chdir(home + 5) < 0)
910 perror("Failed to change directory");
914 execve(argv[0], argv, envp);
916 execl("/bin/sh", "sh", "-c", cmdname, NULL);
921 printf("New process %d created\n", pid);
927 corpse = waitpid(WAIT_ANY, &status, 0);
928 if (corpse < 0 || corpse == 0)
931 if (WIFEXITED(status))
932 printf("Process %d exited with status %d\n",
933 corpse, WEXITSTATUS(status));
934 else if (WIFSIGNALED(status))
935 printf("Process %d terminated with signal %d\n",
936 corpse, WTERMSIG(status));
937 else if (WIFSTOPPED(status))
938 printf("Process %d stopped with signal %d\n",
939 corpse, WSTOPSIG(status));
940 else if (WIFCONTINUED(status))
941 printf("Process %d continued\n", corpse);
943 if (corpse == dbus_pid) {
944 printf("D-Bus system daemon terminated\n");
948 if (corpse == dbus_session_pid) {
949 printf("D-Bus session daemon terminated\n");
950 dbus_session_pid = -1;
953 if (corpse == daemon_pid) {
954 printf("Bluetooth daemon terminated\n");
958 if (corpse == emulator_pid) {
959 printf("Bluetooth emulator terminated\n");
963 if (corpse == monitor_pid) {
964 printf("Bluetooth monitor terminated\n");
968 if (corpse == udevd_pid) {
969 printf("udevd terminated\n");
983 kill(daemon_pid, SIGTERM);
986 kill(dbus_pid, SIGTERM);
988 if (dbus_session_pid > 0)
989 kill(dbus_session_pid, SIGTERM);
991 if (emulator_pid > 0)
992 kill(dbus_pid, SIGTERM);
995 kill(monitor_pid, SIGTERM);
998 kill(udevd_pid, SIGTERM);
1004 static void run_tests(void)
1006 char cmdline[CMDLINE_MAX], *ptr, *cmds, *home = NULL;
1009 fp = fopen("/proc/cmdline", "re");
1011 fprintf(stderr, "Failed to open kernel command line\n");
1015 ptr = fgets(cmdline, sizeof(cmdline), fp);
1019 fprintf(stderr, "Failed to read kernel command line\n");
1023 ptr = strstr(cmdline, "TESTARGS=");
1025 fprintf(stderr, "No test command section found\n");
1030 ptr = strchr(cmds, '\'');
1032 fprintf(stderr, "Malformed test command section\n");
1038 ptr = strstr(cmdline, "TESTAUTO=1");
1040 printf("Automatic test execution requested\n");
1044 ptr = strstr(cmdline, "TESTDEVS=1");
1046 printf("Attachment of devices requested\n");
1050 ptr = strstr(cmdline, "TESTDBUS=1");
1052 printf("D-Bus system daemon requested\n");
1056 ptr = strstr(cmdline, "TESTDBUSSESSION=1");
1058 printf("D-Bus session daemon requested\n");
1059 start_dbus_session = true;
1062 ptr = strstr(cmdline, "TESTDAEMON=1");
1064 printf("bluetoothd requested\n");
1065 start_daemon = true;
1068 ptr = strstr(cmdline, "TESTMONITOR=1");
1070 printf("Monitor requested\n");
1071 start_monitor = true;
1074 ptr = strstr(cmdline, "TESTEMULATOR=1");
1076 printf("Emulator requested\n");
1077 start_emulator = true;
1080 ptr = strstr(cmdline, "TESTAUDIO=1");
1082 printf("Audio support requested\n");
1083 audio_support = true;
1086 ptr = strstr(cmdline, "TESTHOME=");
1089 ptr = strpbrk(home + 9, " \r\n");
1094 run_command(cmds, home);
1097 static void usage(void)
1099 printf("test-runner - Automated test execution utility\n"
1101 printf("\ttest-runner [options] [--] <command> [args]\n");
1103 "\t-a, --auto Find tests and run them\n"
1104 "\t-b, --dbus Start D-Bus system daemon\n"
1105 "\t-s, --dbus-session Start D-Bus session daemon\n"
1106 "\t-d, --daemon Start bluetoothd\n"
1107 "\t-m, --monitor Start btmon\n"
1108 "\t-l, --emulator Start btvirt\n"
1109 "\t-u, --unix [path] Provide serial device\n"
1110 "\t-q, --qemu <path> QEMU binary\n"
1111 "\t-k, --kernel <image> Kernel image (bzImage)\n"
1112 "\t-A, --audio Add audio support\n"
1113 "\t-h, --help Show help options\n");
1116 static const struct option main_options[] = {
1117 { "all", no_argument, NULL, 'a' },
1118 { "auto", no_argument, NULL, 'a' },
1119 { "dbus", no_argument, NULL, 'b' },
1120 { "dbus-session", no_argument, NULL, 's' },
1121 { "unix", no_argument, NULL, 'u' },
1122 { "daemon", no_argument, NULL, 'd' },
1123 { "emulator", no_argument, NULL, 'l' },
1124 { "monitor", no_argument, NULL, 'm' },
1125 { "qemu", required_argument, NULL, 'q' },
1126 { "kernel", required_argument, NULL, 'k' },
1127 { "audio", no_argument, NULL, 'A' },
1128 { "version", no_argument, NULL, 'v' },
1129 { "help", no_argument, NULL, 'h' },
1133 int main(int argc, char *argv[])
1135 if (getpid() == 1 && getppid() == 0) {
1140 reboot(RB_AUTOBOOT);
1141 return EXIT_SUCCESS;
1147 opt = getopt_long(argc, argv, "aubdslmq:k:Avh", main_options,
1163 start_dbus_session = true;
1167 start_daemon = true;
1170 start_emulator = true;
1173 start_monitor = true;
1176 qemu_binary = optarg;
1179 kernel_image = optarg;
1182 audio_support = true;
1185 printf("%s\n", VERSION);
1186 return EXIT_SUCCESS;
1189 return EXIT_SUCCESS;
1191 return EXIT_FAILURE;
1196 if (argc - optind > 0) {
1197 fprintf(stderr, "Invalid command line parameters\n");
1198 return EXIT_FAILURE;
1201 if (argc - optind < 1) {
1202 fprintf(stderr, "Failed to specify test command\n");
1203 return EXIT_FAILURE;
1207 own_binary = argv[0];
1208 test_argv = argv + optind;
1209 test_argc = argc - optind;
1212 qemu_binary = find_qemu();
1214 fprintf(stderr, "No default QEMU binary found\n");
1215 return EXIT_FAILURE;
1219 if (!kernel_image) {
1220 kernel_image = find_kernel();
1221 if (!kernel_image) {
1222 fprintf(stderr, "No default kernel image found\n");
1223 return EXIT_FAILURE;
1227 printf("Using QEMU binary %s\n", qemu_binary);
1228 printf("Using kernel image %s\n", kernel_image);
1232 return EXIT_SUCCESS;