blob: 66efc37ec5dfd29ddd977918f6e233f47c8fc4f5 [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 */
Juan Cespedese1887051998-03-10 00:08:41 +010019char * opt_u = NULL; /* username to run command as */
Juan Cespedes5e01f651998-03-08 22:31:44 +010020
21/* List of pids given to option -p: */
22struct opt_p_t * opt_p = NULL; /* attach to process with a given pid */
23
24static void usage(void)
25{
26 fprintf(stderr, "Usage: ltrace [-dfiLS] [-a column] [-s strlen] [-o filename]\n"
Juan Cespedese1887051998-03-10 00:08:41 +010027 " [-u username] [-p pid] ... [command [arg ...]]\n\n");
Juan Cespedes5e01f651998-03-08 22:31:44 +010028}
29
30static char * search_for_command(char * filename)
31{
32 static char pathname[PATH_MAX];
33 char *path;
34 int m, n;
35
36 if (strchr(filename, '/')) {
37 return filename;
38 }
39 for (path = getenv("PATH"); path && *path; path += m) {
40 if (strchr(path, ':')) {
41 n = strchr(path, ':') - path;
42 m = n + 1;
43 } else {
44 m = n = strlen(path);
45 }
46 strncpy(pathname, path, n);
47 if (n && pathname[n - 1] != '/') {
48 pathname[n++] = '/';
49 }
50 strcpy(pathname + n, filename);
51 if (!access(pathname, X_OK)) {
52 return pathname;
53 }
54 }
55 return filename;
56}
57
58char ** process_options(int argc, char **argv)
59{
60 char *nextchar = NULL;
61
62 output = stderr;
63
64 while(1) {
65 if (!nextchar || !(*nextchar)) {
66 if (!argv[1] || argv[1][0] != '-' || !argv[1][1]) {
67 break;
68 }
69 nextchar = &argv[1][1];
70 argc--; argv++;
71 }
72 switch (*nextchar++) {
73 case 'a': opt_a = atoi(argv[1]);
74 argc--; argv++;
75 break;
76 case 'd': opt_d++;
77 break;
78 case 'o': output = fopen(argv[1], "w");
79 if (!output) {
80 fprintf(stderr, "Can't open %s for output: %s\n", argv[1], strerror(errno));
81 exit(1);
82 }
83 argc--; argv++;
84 break;
85 case 'i': opt_i++;
86 break;
87 case 's': opt_s = atoi(argv[1]);
88 argc--; argv++;
89 break;
90 case 'L': opt_L = 0;
91 break;
92 case 'S': opt_S = 1;
93 break;
94 case 'f': opt_f = 1;
95 break;
Juan Cespedese1887051998-03-10 00:08:41 +010096 case 'u': opt_u = argv[1];
97 argc--; argv++;
98 break;
Juan Cespedes5e01f651998-03-08 22:31:44 +010099 case 'p':
100 {
101 struct opt_p_t * tmp = malloc(sizeof(struct opt_p_t));
102 if (!tmp) {
103 perror("malloc");
104 exit(1);
105 }
106 tmp->pid = atoi(argv[1]);
107 argc--; argv++;
108 break;
109 }
110 default: fprintf(stderr, "Unknown option '%c'\n", *(nextchar-1));
111 usage();
112 exit(1);
113 }
114 }
115
116 if (argc<2) {
117 usage();
118 exit(1);
119 }
120 command = search_for_command(argv[1]);
121 return &argv[1];
122}