blob: f5b8874c715e1905d075872c50b44e6dabf99ae3 [file] [log] [blame]
Juan Cespedes5e01f651998-03-08 22:31:44 +01001#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}