options.c revision 5e01f654d83a95f2acffa86df57a4c2db9b0cae9
1#include <string.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <errno.h>
5#include <limits.h>
6
7#include "ltrace.h"
8#include "options.h"
9#include "defs.h"
10
11FILE * output;
12int opt_a = DEFAULT_ACOLUMN;	/* default alignment column for results */
13int opt_d = 0;			/* debug */
14int opt_i = 0;			/* instruction pointer */
15int opt_s = DEFAULT_STRLEN;	/* default maximum # of bytes printed in strings */
16int opt_S = 0;			/* display syscalls */
17int opt_L = 1;			/* display library calls */
18int opt_f = 0;			/* trace child processes as they are created */
19
20/* List of pids given to option -p: */
21struct opt_p_t * opt_p = NULL;	/* attach to process with a given pid */
22
23static void usage(void)
24{
25	fprintf(stderr, "Usage: ltrace [-dfiLS] [-a column] [-s strlen] [-o filename]\n"
26			"              [-p pid] ... [command [arg ...]]\n\n");
27}
28
29static char * search_for_command(char * filename)
30{
31	static char pathname[PATH_MAX];
32	char *path;
33	int m, n;
34
35	if (strchr(filename, '/')) {
36		return filename;
37	}
38	for (path = getenv("PATH"); path && *path; path += m) {
39		if (strchr(path, ':')) {
40			n = strchr(path, ':') - path;
41			m = n + 1;
42		} else {
43			m = n = strlen(path);
44		}
45		strncpy(pathname, path, n);
46		if (n && pathname[n - 1] != '/') {
47			pathname[n++] = '/';
48		}
49		strcpy(pathname + n, filename);
50		if (!access(pathname, X_OK)) {
51			return pathname;
52		}
53	}
54	return filename;
55}
56
57char ** process_options(int argc, char **argv)
58{
59	char *nextchar = NULL;
60
61	output = stderr;
62
63	while(1) {
64		if (!nextchar || !(*nextchar)) {
65			if (!argv[1] || argv[1][0] != '-' || !argv[1][1]) {
66				break;
67			}
68			nextchar = &argv[1][1];
69			argc--; argv++;
70		}
71		switch (*nextchar++) {
72			case 'a':	opt_a = atoi(argv[1]);
73					argc--; argv++;
74					break;
75			case 'd':	opt_d++;
76					break;
77			case 'o':	output = fopen(argv[1], "w");
78					if (!output) {
79						fprintf(stderr, "Can't open %s for output: %s\n", argv[1], strerror(errno));
80						exit(1);
81					}
82					argc--; argv++;
83					break;
84			case 'i':	opt_i++;
85					break;
86			case 's':	opt_s = atoi(argv[1]);
87					argc--; argv++;
88					break;
89			case 'L':	opt_L = 0;
90					break;
91			case 'S':	opt_S = 1;
92					break;
93			case 'f':	opt_f = 1;
94					break;
95			case 'p':
96				{
97					struct opt_p_t * tmp = malloc(sizeof(struct opt_p_t));
98					if (!tmp) {
99						perror("malloc");
100						exit(1);
101					}
102					tmp->pid = atoi(argv[1]);
103					argc--; argv++;
104					break;
105				}
106			default:	fprintf(stderr, "Unknown option '%c'\n", *(nextchar-1));
107					usage();
108					exit(1);
109		}
110	}
111
112	if (argc<2) {
113		usage();
114		exit(1);
115	}
116	command = search_for_command(argv[1]);
117	return &argv[1];
118}
119