mirror of
https://github.com/sstefani/mtrace.git
synced 2026-02-08 10:46:42 +08:00
option handling cleanup
This commit is contained in:
parent
66c24caa72
commit
033747ca32
93
options.c
93
options.c
@ -3,8 +3,6 @@
|
|||||||
* Copyright (C) 2015 Stefani Seibold <stefani@seibold.net>
|
* Copyright (C) 2015 Stefani Seibold <stefani@seibold.net>
|
||||||
* This file is based on the ltrace source
|
* This file is based on the ltrace source
|
||||||
*
|
*
|
||||||
* This work was sponsored by Rohde & Schwarz GmbH & Co. KG, Munich.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* modify it under the terms of the GNU General Public License as
|
||||||
* published by the Free Software Foundation; either version 2 of the
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
@ -74,8 +72,8 @@ static void usage(void)
|
|||||||
"\n"
|
"\n"
|
||||||
" -a, --autoscan scan memory on exit of a traced program\n"
|
" -a, --autoscan scan memory on exit of a traced program\n"
|
||||||
" -b, --binpath=path binary search path (may be repeated)\n"
|
" -b, --binpath=path binary search path (may be repeated)\n"
|
||||||
" -c, --client connect to socket (path or address)\n"
|
" -c, --client=addr connect to socket (path or address)\n"
|
||||||
" -C, --cwd set current working directory\n"
|
" -C, --cwd=path use as current working directory for traced process\n"
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
" -D, --debug=MASK enable debugging (see -Dh or --debug=help)\n"
|
" -D, --debug=MASK enable debugging (see -Dh or --debug=help)\n"
|
||||||
" -Dh, --debug=help show help on debugging\n"
|
" -Dh, --debug=help show help on debugging\n"
|
||||||
@ -83,7 +81,7 @@ static void usage(void)
|
|||||||
" -d, --depth=NR backtrace stack depth (default: " STR(DEFAULT_STACK) ")\n"
|
" -d, --depth=NR backtrace stack depth (default: " STR(DEFAULT_STACK) ")\n"
|
||||||
" -e, --follow-exec follow exec() system calls\n"
|
" -e, --follow-exec follow exec() system calls\n"
|
||||||
" -F, --config=FILE load alternate configuration file (may be repeated)\n"
|
" -F, --config=FILE load alternate configuration file (may be repeated)\n"
|
||||||
" -f, --follow-child trace forked children\n"
|
" -f, --follow-fork trace forked children\n"
|
||||||
" -h, --help display this help and exit\n"
|
" -h, --help display this help and exit\n"
|
||||||
" -i, --interactive interactive client mode\n"
|
" -i, --interactive interactive client mode\n"
|
||||||
" -k, --kill abort mtrace on unexpected error conditon\n"
|
" -k, --kill abort mtrace on unexpected error conditon\n"
|
||||||
@ -126,9 +124,9 @@ static char *search_for_command(char *filename)
|
|||||||
char *path;
|
char *path;
|
||||||
int m, n;
|
int m, n;
|
||||||
|
|
||||||
if (strchr(filename, '/')) {
|
if (strchr(filename, '/'))
|
||||||
return filename;
|
return filename;
|
||||||
}
|
|
||||||
for (path = getenv("PATH"); path && *path; path += m) {
|
for (path = getenv("PATH"); path && *path; path += m) {
|
||||||
if (strchr(path, ':')) {
|
if (strchr(path, ':')) {
|
||||||
n = strchr(path, ':') - path;
|
n = strchr(path, ':') - path;
|
||||||
@ -136,18 +134,21 @@ static char *search_for_command(char *filename)
|
|||||||
} else {
|
} else {
|
||||||
m = n = strlen(path);
|
m = n = strlen(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n + strlen(filename) + 1 >= PATH_MAX) {
|
if (n + strlen(filename) + 1 >= PATH_MAX) {
|
||||||
fprintf(stderr, "Error: filename too long.\n");
|
fprintf(stderr, "Error: filename too long.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(pathname, path, n);
|
strncpy(pathname, path, n);
|
||||||
if (n && pathname[n - 1] != '/') {
|
|
||||||
|
if (n && pathname[n - 1] != '/')
|
||||||
pathname[n++] = '/';
|
pathname[n++] = '/';
|
||||||
}
|
|
||||||
strcpy(pathname + n, filename);
|
strcpy(pathname + n, filename);
|
||||||
if (!access(pathname, X_OK)) {
|
|
||||||
|
if (!access(pathname, X_OK))
|
||||||
return pathname;
|
return pathname;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
@ -192,28 +193,31 @@ static void def_config(void)
|
|||||||
|
|
||||||
if (path) {
|
if (path) {
|
||||||
if (asprintf(&filename, "%s/.mtrace", path) != -1) {
|
if (asprintf(&filename, "%s/.mtrace", path) != -1) {
|
||||||
if (add_opt_F(filename))
|
if (!add_opt_F(filename))
|
||||||
free(filename);
|
return;
|
||||||
|
free(filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
path = getenv("XDG_CONFIG_HOME");
|
path = getenv("XDG_CONFIG_HOME");
|
||||||
if (path) {
|
if (path) {
|
||||||
if (asprintf(&filename, "%s/mtrace", path) != -1) {
|
if (asprintf(&filename, "%s/mtrace", path) != -1) {
|
||||||
if (add_opt_F(filename))
|
if (!add_opt_F(filename))
|
||||||
free(filename);
|
return;
|
||||||
}
|
free(filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (asprintf(&filename, "%s/mtrace.conf", SYSCONFDIR) != -1) {
|
if (asprintf(&filename, "%s/mtrace.conf", SYSCONFDIR) != -1) {
|
||||||
if (add_opt_F(filename))
|
if (!add_opt_F(filename))
|
||||||
free(filename);
|
return;
|
||||||
|
free(filename);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
if (asprintf(&filename, "%s/mtrace.conf", "/etc") != -1) {
|
if (asprintf(&filename, "%s/mtrace.conf", "/etc") != -1) {
|
||||||
if (add_opt_F(filename))
|
if (!add_opt_F(filename))
|
||||||
free(filename);
|
return;
|
||||||
|
free(filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,6 +236,8 @@ static int parse_int(const char *optarg, char opt, int min, int max)
|
|||||||
|
|
||||||
char **process_options(int argc, char **argv)
|
char **process_options(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
char *output = NULL;
|
||||||
|
|
||||||
progname = argv[0];
|
progname = argv[0];
|
||||||
|
|
||||||
options.auto_scan = 0;
|
options.auto_scan = 0;
|
||||||
@ -268,7 +274,7 @@ char **process_options(int argc, char **argv)
|
|||||||
{ "debug", 1, 0, 'D' },
|
{ "debug", 1, 0, 'D' },
|
||||||
{ "depth", 1, 0, 'd' },
|
{ "depth", 1, 0, 'd' },
|
||||||
{ "help", 0, 0, 'h' },
|
{ "help", 0, 0, 'h' },
|
||||||
{ "follow-child", 0, 0, 'f'},
|
{ "follow-fork", 0, 0, 'f'},
|
||||||
{ "follow-exec", 0, 0, 'e' },
|
{ "follow-exec", 0, 0, 'e' },
|
||||||
{ "interactive", 0, 0, 'i' },
|
{ "interactive", 0, 0, 'i' },
|
||||||
{ "kill", 0, 0, 'k' },
|
{ "kill", 0, 0, 'k' },
|
||||||
@ -363,13 +369,7 @@ char **process_options(int argc, char **argv)
|
|||||||
options.listen = optarg;
|
options.listen = optarg;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
options.output = fopen(optarg, "w");
|
output = optarg;
|
||||||
if (!options.output) {
|
|
||||||
fprintf(stderr, "can't open %s for writing: %s\n", optarg, strerror(errno));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
setvbuf(options.output, (char *)NULL, _IOLBF, 0);
|
|
||||||
fcntl(fileno(options.output), F_SETFD, FD_CLOEXEC);
|
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
{
|
{
|
||||||
@ -460,6 +460,9 @@ char **process_options(int argc, char **argv)
|
|||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
|
if (argc > 0)
|
||||||
|
options.command = search_for_command(argv[0]);
|
||||||
|
|
||||||
if (options.sort_by == OPT_SORT_LEAKS || options.sort_by == OPT_SORT_BYTES_LEAKED)
|
if (options.sort_by == OPT_SORT_LEAKS || options.sort_by == OPT_SORT_BYTES_LEAKED)
|
||||||
options.auto_scan = 1;
|
options.auto_scan = 1;
|
||||||
|
|
||||||
@ -489,9 +492,15 @@ char **process_options(int argc, char **argv)
|
|||||||
err_usage();
|
err_usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.interactive && (!options.client && !options.opt_p)) {
|
if (options.interactive) {
|
||||||
fprintf(stderr, "%s: interactive mode can only invoked in -p or -c mode\n", progname);
|
if ((!options.client && !options.opt_p) || options.command) {
|
||||||
err_usage();
|
fprintf(stderr, "%s: interactive mode can only invoked in -p or -c mode\n", progname);
|
||||||
|
err_usage();
|
||||||
|
}
|
||||||
|
output = NULL;
|
||||||
|
|
||||||
|
if (options.auto_scan)
|
||||||
|
fprintf(stderr, "%s: auto scan ignored in interactive mode\n", progname);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.auto_scan && options.server) {
|
if (options.auto_scan && options.server) {
|
||||||
@ -522,8 +531,16 @@ char **process_options(int argc, char **argv)
|
|||||||
if (!options.opt_F)
|
if (!options.opt_F)
|
||||||
def_config();
|
def_config();
|
||||||
|
|
||||||
if (argc > 0)
|
if (output) {
|
||||||
options.command = search_for_command(argv[0]);
|
options.output = fopen(output, "w");
|
||||||
|
|
||||||
|
if (!options.output) {
|
||||||
|
fprintf(stderr, "can't open %s for writing: %s\n", output, strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
setvbuf(options.output, (char *)NULL, _IOLBF, 0);
|
||||||
|
fcntl(fileno(options.output), F_SETFD, FD_CLOEXEC);
|
||||||
|
}
|
||||||
|
|
||||||
return &argv[0];
|
return &argv[0];
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user