blob: facea039d44b1209bfd23866adf0541682dd3f49 [file] [log] [blame]
Juan Cespedes1c2be911997-06-09 01:12:01 +02001#include <stdio.h>
Juan Cespedes23658aa1997-08-27 22:27:36 +02002#include <stdlib.h>
3#include <sys/param.h>
Juan Cespedes1c2be911997-06-09 01:12:01 +02004#include <errno.h>
5#include <unistd.h>
Juan Cespedes23658aa1997-08-27 22:27:36 +02006#include <string.h>
Juan Cespedes1c2be911997-06-09 01:12:01 +02007
Juan Cespedes96935a91997-08-09 23:45:39 +02008#include "elf.h"
Juan Cespedesef04ba41997-08-22 21:55:45 +02009#include "process.h"
Juan Cespedes3268a161997-08-25 16:45:22 +020010#include "output.h"
Juan Cespedes96935a91997-08-09 23:45:39 +020011
Juan Cespedes96935a91997-08-09 23:45:39 +020012extern void read_config_file(const char *);
Juan Cespedes24c82531997-06-25 00:02:58 +020013
Juan Cespedes5b2f9811997-07-17 00:05:10 +020014FILE * output = stderr;
Juan Cespedes5e4455b1997-08-24 01:48:26 +020015int opt_d = 0; /* debug */
16int opt_i = 0; /* instruction pointer */
17int opt_S = 0; /* syscalls */
Juan Cespedes5b2f9811997-07-17 00:05:10 +020018
Juan Cespedes5b2f9811997-07-17 00:05:10 +020019static void usage(void)
20{
Juan Cespedes5e4455b1997-08-24 01:48:26 +020021 fprintf(stderr,"Usage: ltrace [-d] [-i] [-S] [-o filename] command [arg ...]\n\n");
Juan Cespedes5b2f9811997-07-17 00:05:10 +020022}
23
Juan Cespedes23658aa1997-08-27 22:27:36 +020024static char * search_for_command(char * filename)
25{
26 static char pathname[MAXPATHLEN];
27 char *path;
28 int m, n;
29
30 if (strchr(filename, '/')) {
31 return filename;
32 }
33 for (path = getenv("PATH"); path && *path; path += m) {
34 if (strchr(path, ':')) {
35 n = strchr(path, ':') - path;
36 m = n + 1;
37 } else {
38 m = n = strlen(path);
39 }
40 strncpy(pathname, path, n);
41 if (n && pathname[n - 1] != '/') {
42 pathname[n++] = '/';
43 }
44 strcpy(pathname + n, filename);
45 if (!access(pathname, X_OK)) {
46 break;
47 }
48 }
49 if (access(pathname, X_OK)) {
50 return NULL;
51 } else {
52 return pathname;
53 }
54}
55
Juan Cespedes1c2be911997-06-09 01:12:01 +020056int main(int argc, char **argv)
57{
Juan Cespedesef04ba41997-08-22 21:55:45 +020058 int pid;
Juan Cespedes23658aa1997-08-27 22:27:36 +020059 char * command;
Juan Cespedesad783621997-06-10 17:11:33 +020060
Juan Cespedes5b2f9811997-07-17 00:05:10 +020061 while ((argc>2) && (argv[1][0] == '-') && (argv[1][2] == '\0')) {
Juan Cespedesad783621997-06-10 17:11:33 +020062 switch(argv[1][1]) {
Juan Cespedes1afec691997-08-23 21:31:46 +020063 case 'd': opt_d++;
Juan Cespedesad783621997-06-10 17:11:33 +020064 break;
Juan Cespedes5b2f9811997-07-17 00:05:10 +020065 case 'o': output = fopen(argv[2], "w");
66 if (!output) {
67 fprintf(stderr, "Can't open %s for output: %s\n", argv[2], sys_errlist[errno]);
68 exit(1);
69 }
70 argc--; argv++;
71 break;
Juan Cespedes1afec691997-08-23 21:31:46 +020072 case 'i': opt_i++;
73 break;
Juan Cespedes5e4455b1997-08-24 01:48:26 +020074 case 'S': opt_S++;
75 break;
Juan Cespedesad783621997-06-10 17:11:33 +020076 default: fprintf(stderr, "Unknown option '%c'\n", argv[1][1]);
Juan Cespedes5b2f9811997-07-17 00:05:10 +020077 usage();
Juan Cespedesad783621997-06-10 17:11:33 +020078 exit(1);
79 }
80 argc--; argv++;
81 }
Juan Cespedes1c2be911997-06-09 01:12:01 +020082
83 if (argc<2) {
Juan Cespedes5b2f9811997-07-17 00:05:10 +020084 usage();
Juan Cespedes1c2be911997-06-09 01:12:01 +020085 exit(1);
86 }
Juan Cespedes23658aa1997-08-27 22:27:36 +020087 command = search_for_command(argv[1]);
88 if (!command) {
89 fprintf(stderr, "%s: command not found\n", argv[1]);
90 exit(1);
91 }
92 if (!read_elf(command)) {
93 fprintf(stderr, "%s: Not dynamically linked\n", command);
Juan Cespedes1c2be911997-06-09 01:12:01 +020094 exit(1);
95 }
Juan Cespedesef04ba41997-08-22 21:55:45 +020096
Juan Cespedes1afec691997-08-23 21:31:46 +020097 if (opt_d>0) {
Juan Cespedes3268a161997-08-25 16:45:22 +020098 send_line("Reading config file(s)...");
Juan Cespedes1afec691997-08-23 21:31:46 +020099 }
Juan Cespedes96935a91997-08-09 23:45:39 +0200100 read_config_file("/etc/ltrace.cfg");
101 read_config_file(".ltracerc");
Juan Cespedes1afec691997-08-23 21:31:46 +0200102
Juan Cespedes23658aa1997-08-27 22:27:36 +0200103 pid = execute_process(command, argv+1);
Juan Cespedes1afec691997-08-23 21:31:46 +0200104 if (opt_d>0) {
Juan Cespedes3268a161997-08-25 16:45:22 +0200105 send_line("pid %u launched", pid);
Juan Cespedes1afec691997-08-23 21:31:46 +0200106 }
Juan Cespedesad783621997-06-10 17:11:33 +0200107
Juan Cespedes1c2be911997-06-09 01:12:01 +0200108 while(1) {
Juan Cespedes3268a161997-08-25 16:45:22 +0200109 wait_for_child();
Juan Cespedes1c2be911997-06-09 01:12:01 +0200110 }
Juan Cespedesef04ba41997-08-22 21:55:45 +0200111
Juan Cespedes1c2be911997-06-09 01:12:01 +0200112 exit(0);
113}