Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * rv tool, the interface for the Linux kernel RV subsystem and home of
  4 * user-space controlled monitors.
  5 *
  6 * Copyright (C) 2022 Red Hat Inc, Daniel Bristot de Oliveira <bristot@kernel.org>
  7 */
  8
  9#include <stdlib.h>
 10#include <signal.h>
 11#include <unistd.h>
 12
 13#include <trace.h>
 14#include <utils.h>
 15#include <in_kernel.h>
 16
 17static int stop_session;
 18
 19/*
 20 * stop_rv - tell monitors to stop
 21 */
 22static void stop_rv(int sig)
 23{
 24	stop_session = 1;
 25}
 26
 27/**
 28 * should_stop - check if the monitor should stop.
 29 *
 30 * Returns 1 if the monitor should stop, 0 otherwise.
 31 */
 32int should_stop(void)
 33{
 34	return stop_session;
 35}
 36
 37/*
 38 * rv_list - list all available monitors
 39 */
 40static void rv_list(int argc, char **argv)
 41{
 42	static const char *const usage[] = {
 43		"",
 44		"  usage: rv list [-h]",
 45		"",
 46		"	list all available monitors",
 47		"",
 48		"	-h/--help: print this menu",
 49		NULL,
 50	};
 51	int i;
 52
 53	if (argc > 1) {
 54		fprintf(stderr, "rv version %s\n", VERSION);
 55
 56		/* more than 1 is always usage */
 57		for (i = 0; usage[i]; i++)
 58			fprintf(stderr, "%s\n", usage[i]);
 59
 60		/* but only -h is valid */
 61		if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
 62			exit(0);
 63		else
 64			exit(1);
 65	}
 66
 67	ikm_list_monitors();
 68	exit(0);
 69}
 70
 71/*
 72 * rv_mon - try to run a monitor passed as argument
 73 */
 74static void rv_mon(int argc, char **argv)
 75{
 76	char *monitor_name;
 77	int i, run = 0;
 78
 79	static const char *const usage[] = {
 80		"",
 81		"  usage: rv mon [-h] monitor [monitor options]",
 82		"",
 83		"	run a monitor",
 84		"",
 85		"	-h/--help: print this menu",
 86		"",
 87		"	monitor [monitor options]: the monitor, passing",
 88		"	the arguments to the [monitor options]",
 89		NULL,
 90	};
 91
 92	/* requires at least one argument */
 93	if (argc == 1) {
 94
 95		fprintf(stderr, "rv version %s\n", VERSION);
 96
 97		for (i = 0; usage[i]; i++)
 98			fprintf(stderr, "%s\n", usage[i]);
 99		exit(1);
100	} else if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
101
102		fprintf(stderr, "rv version %s\n", VERSION);
103
104		for (i = 0; usage[i]; i++)
105			fprintf(stderr, "%s\n", usage[i]);
106		exit(0);
107	}
108
109	monitor_name = argv[1];
110	/*
111	 * Call all possible monitor implementations, looking
112	 * for the [monitor].
113	 */
114	run += ikm_run_monitor(monitor_name, argc-1, &argv[1]);
115
116	if (!run)
117		err_msg("rv: monitor %s does not exist\n", monitor_name);
118	exit(!run);
119}
120
121static void usage(int exit_val, const char *fmt, ...)
122{
123	char message[1024];
124	va_list ap;
125	int i;
126
127	static const char *const usage[] = {
128		"",
129		"  usage: rv command [-h] [command_options]",
130		"",
131		"	-h/--help: print this menu",
132		"",
133		"	command: run one of the following command:",
134		"	  list: list all available monitors",
135		"	  mon:  run a monitor",
136		"",
137		"	[command options]: each command has its own set of options",
138		"		           run rv command -h for further information",
139		NULL,
140	};
141
142	va_start(ap, fmt);
143	vsnprintf(message, sizeof(message), fmt, ap);
144	va_end(ap);
145
146	fprintf(stderr, "rv version %s: %s\n", VERSION, message);
147
148	for (i = 0; usage[i]; i++)
149		fprintf(stderr, "%s\n", usage[i]);
150
151	exit(exit_val);
152}
153
154/*
155 * main - select which main sending the command
156 *
157 * main itself redirects the arguments to the sub-commands
158 * to handle the options.
159 *
160 * subcommands should exit.
161 */
162int main(int argc, char **argv)
163{
164	if (geteuid())
165		usage(1, "%s needs root permission", argv[0]);
166
167	if (argc <= 1)
168		usage(1, "%s requires a command", argv[0]);
169
170	if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
171		usage(0, "help");
172
173	if (!strcmp(argv[1], "list"))
174		rv_list(--argc, &argv[1]);
175
176	if (!strcmp(argv[1], "mon")) {
177		/*
178		 * monitor's main should monitor should_stop() function.
179		 * and exit.
180		 */
181		signal(SIGINT, stop_rv);
182
183		rv_mon(argc - 1, &argv[1]);
184	}
185
186	/* invalid sub-command */
187	usage(1, "%s does not know the %s command, old version?", argv[0], argv[1]);
188}