blob: 0b556d82d5668e32c9029371a9ac104631fff2d0 [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 Cespedes5e0acdb1998-04-04 08:34:07 +020020int opt_t = 0; /* print absolute timestamp */
Juan Cespedes5e01f651998-03-08 22:31:44 +010021
22/* List of pids given to option -p: */
23struct opt_p_t * opt_p = NULL; /* attach to process with a given pid */
24
25static void usage(void)
26{
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020027 fprintf(stderr, "Usage: ltrace [-dfiLSttt] [-a column] [-s strlen] [-o filename]\n"
Juan Cespedese1887051998-03-10 00:08:41 +010028 " [-u username] [-p pid] ... [command [arg ...]]\n\n");
Juan Cespedes5e01f651998-03-08 22:31:44 +010029}
30
31static char * search_for_command(char * filename)
32{
33 static char pathname[PATH_MAX];
34 char *path;
35 int m, n;
36
37 if (strchr(filename, '/')) {
38 return filename;
39 }
40 for (path = getenv("PATH"); path && *path; path += m) {
41 if (strchr(path, ':')) {
42 n = strchr(path, ':') - path;
43 m = n + 1;
44 } else {
45 m = n = strlen(path);
46 }
47 strncpy(pathname, path, n);
48 if (n && pathname[n - 1] != '/') {
49 pathname[n++] = '/';
50 }
51 strcpy(pathname + n, filename);
52 if (!access(pathname, X_OK)) {
53 return pathname;
54 }
55 }
56 return filename;
57}
58
59char ** process_options(int argc, char **argv)
60{
61 char *nextchar = NULL;
62
63 output = stderr;
64
65 while(1) {
66 if (!nextchar || !(*nextchar)) {
67 if (!argv[1] || argv[1][0] != '-' || !argv[1][1]) {
68 break;
69 }
70 nextchar = &argv[1][1];
71 argc--; argv++;
72 }
73 switch (*nextchar++) {
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020074 case 'd': opt_d++;
75 break;
76 case 'f': opt_f = 1;
77 break;
78 case 'i': opt_i++;
79 break;
80 case 'L': opt_L = 0;
81 break;
82 case 'S': opt_S = 1;
83 break;
84 case 't': opt_t++;
85 break;
Juan Cespedes1fe93d51998-03-13 00:29:21 +010086 case 'a': if (!argv[1]) { usage(); exit(1); }
87 opt_a = atoi(argv[1]);
Juan Cespedes5e01f651998-03-08 22:31:44 +010088 argc--; argv++;
89 break;
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020090 case 's': if (!argv[1]) { usage(); exit(1); }
91 opt_s = atoi(argv[1]);
92 argc--; argv++;
Juan Cespedes5e01f651998-03-08 22:31:44 +010093 break;
Juan Cespedes1fe93d51998-03-13 00:29:21 +010094 case 'o': if (!argv[1]) { usage(); exit(1); }
95 output = fopen(argv[1], "w");
Juan Cespedes5e01f651998-03-08 22:31:44 +010096 if (!output) {
97 fprintf(stderr, "Can't open %s for output: %s\n", argv[1], strerror(errno));
98 exit(1);
99 }
100 argc--; argv++;
101 break;
Juan Cespedes1fe93d51998-03-13 00:29:21 +0100102 case 'u': if (!argv[1]) { usage(); exit(1); }
103 opt_u = argv[1];
Juan Cespedese1887051998-03-10 00:08:41 +0100104 argc--; argv++;
105 break;
Juan Cespedes1fe93d51998-03-13 00:29:21 +0100106 case 'p': if (!argv[1]) { usage(); exit(1); }
Juan Cespedes5e01f651998-03-08 22:31:44 +0100107 {
108 struct opt_p_t * tmp = malloc(sizeof(struct opt_p_t));
109 if (!tmp) {
110 perror("malloc");
111 exit(1);
112 }
113 tmp->pid = atoi(argv[1]);
Juan Cespedes1fe93d51998-03-13 00:29:21 +0100114 tmp->next = opt_p;
115 opt_p = tmp;
Juan Cespedes5e01f651998-03-08 22:31:44 +0100116 argc--; argv++;
117 break;
118 }
119 default: fprintf(stderr, "Unknown option '%c'\n", *(nextchar-1));
120 usage();
121 exit(1);
122 }
123 }
124
Juan Cespedes1fe93d51998-03-13 00:29:21 +0100125 if (!opt_p && argc<2) {
Juan Cespedes5e01f651998-03-08 22:31:44 +0100126 usage();
127 exit(1);
128 }
Juan Cespedes1fe93d51998-03-13 00:29:21 +0100129 if (argc>1) {
130 command = search_for_command(argv[1]);
131 }
Juan Cespedes5e01f651998-03-08 22:31:44 +0100132 return &argv[1];
133}