124 lines
2.4 KiB
C
124 lines
2.4 KiB
C
/*
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
* Copyright (C) 2019 Philippe Gerum <rpm@xenomai.org>
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <error.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <limits.h>
|
|
#include <ctype.h>
|
|
#include <libgen.h>
|
|
#include <getopt.h>
|
|
#include <uapi/evl/control.h>
|
|
|
|
static char *find_command_dir(const char *arg0)
|
|
{
|
|
char *exepath, *bindir, *cmddir;
|
|
int ret;
|
|
|
|
exepath = malloc(PATH_MAX);
|
|
if (exepath == NULL)
|
|
error(1, ENOMEM, "malloc");
|
|
|
|
ret = readlink("/proc/self/exe", exepath, PATH_MAX);
|
|
if (ret < 0)
|
|
error(1, errno, "readlink");
|
|
|
|
bindir = dirname(exepath);
|
|
ret = asprintf(&cmddir, "%s/libexec", dirname(bindir));
|
|
if (ret < 0)
|
|
error(1, errno, "malloc");
|
|
|
|
return cmddir;
|
|
}
|
|
|
|
static void usage(void)
|
|
{
|
|
fprintf(stderr, "usage: evl [options] <command> [<args>]\n");
|
|
fprintf(stderr, "-P --prefix=<path> set command path prefix\n");
|
|
fprintf(stderr, "-A print required EVL core ABI version\n");
|
|
}
|
|
|
|
#define short_optlist "+P:A"
|
|
|
|
static const struct option options[] = {
|
|
{
|
|
.name = "prefix",
|
|
.has_arg = required_argument,
|
|
.val = 'P'
|
|
},
|
|
{
|
|
.name = "abi",
|
|
.has_arg = no_argument,
|
|
.val = 'A'
|
|
},
|
|
{ /* Sentinel */ }
|
|
};
|
|
|
|
int main(int argc, char *const argv[])
|
|
{
|
|
char *cmddir = NULL, *cmdpath, **cmdargv, *cmd;
|
|
const char *arg0 = argv[0];
|
|
int ret, c, n, cmdargc;
|
|
|
|
opterr = 0;
|
|
|
|
do {
|
|
c = getopt_long(argc, argv, short_optlist, options, NULL);
|
|
switch (c) {
|
|
case 0:
|
|
case 'P':
|
|
cmddir = optarg;
|
|
break;
|
|
case 'A':
|
|
printf("%d\n", EVL_ABI_LEVEL);
|
|
exit(0);
|
|
case '?':
|
|
usage();
|
|
return 2;
|
|
default:
|
|
break;
|
|
}
|
|
} while (c != EOF && c != '?');
|
|
|
|
if (optind >= argc) {
|
|
cmd = "help";
|
|
optind = argc - 1;
|
|
} else {
|
|
if (c == '?') {
|
|
usage();
|
|
return 2;
|
|
}
|
|
cmd = argv[optind];
|
|
}
|
|
|
|
if (cmddir == NULL)
|
|
cmddir = find_command_dir(arg0);
|
|
|
|
ret = asprintf(&cmdpath, "%s/evl-%s", cmddir, cmd);
|
|
if (ret < 0)
|
|
error(1, ENOMEM, "%s", arg0);
|
|
|
|
setenv("EVL_CMDDIR", cmddir, 1);
|
|
setenv("EVL_SYSDIR", "/sys/devices/virtual", 1);
|
|
setenv("EVL_TRACEDIR", "/sys/kernel/debug/tracing", 1);
|
|
|
|
cmdargv = malloc(sizeof(char *) * (argc - optind + 1));
|
|
if (cmdargv == NULL)
|
|
error(1, ENOMEM, "malloc");
|
|
cmdargv[0] = basename(cmdpath);
|
|
for (n = optind + 1, cmdargc = 1; n < argc; n++)
|
|
cmdargv[cmdargc++] = argv[n];
|
|
cmdargv[cmdargc++] = NULL;
|
|
|
|
execv(cmdpath, cmdargv);
|
|
fprintf(stderr, "evl: undefined command '%s'\n", cmd);
|
|
|
|
return 1;
|
|
}
|