blob: 9bc39a98de5580a5ef82fdc735f09c0a0fabadf2 [file] [log] [blame]
Juan Cespedesd44c6b81998-09-25 14:48:42 +02001#if HAVE_CONFIG_H
2#include "config.h"
3#endif
4
Juan Cespedes1c2be911997-06-09 01:12:01 +02005#include <stdio.h>
Juan Cespedes23658aa1997-08-27 22:27:36 +02006#include <stdlib.h>
Juan Cespedes1c2be911997-06-09 01:12:01 +02007#include <unistd.h>
Juan Cespedes23658aa1997-08-27 22:27:36 +02008#include <string.h>
Juan Cespedes5e01f651998-03-08 22:31:44 +01009#include <errno.h>
10#include <sys/param.h>
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020011#include <signal.h>
Juan Cespedes28f60191998-04-12 00:04:39 +020012#include <sys/wait.h>
Juan Cespedesa0ccf392003-02-01 19:02:37 +010013#include <sys/ioctl.h>
Juan Cespedes1c2be911997-06-09 01:12:01 +020014
Juan Cespedes5e01f651998-03-08 22:31:44 +010015#include "ltrace.h"
Juan Cespedes3268a161997-08-25 16:45:22 +020016#include "output.h"
Juan Cespedes28f60191998-04-12 00:04:39 +020017#include "read_config_file.h"
Juan Cespedes5e01f651998-03-08 22:31:44 +010018#include "options.h"
Juan Cespedescac15c32003-01-31 18:58:58 +010019#include "debug.h"
Juan Cespedes96935a91997-08-09 23:45:39 +020020
Juan Cespedesf1bfe202002-03-27 00:22:23 +010021#ifndef SYSCONFDIR
22#define SYSCONFDIR "/etc"
23#endif
24
Juan Cespedes1fe93d51998-03-13 00:29:21 +010025char * command = NULL;
Juan Cespedes5e01f651998-03-08 22:31:44 +010026struct process * list_of_processes = NULL;
Juan Cespedes24c82531997-06-25 00:02:58 +020027
Juan Cespedes28f60191998-04-12 00:04:39 +020028int exiting=0; /* =1 if a SIGINT or SIGTERM has been received */
29
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010030static void
31signal_alarm(int sig) {
Juan Cespedes28f60191998-04-12 00:04:39 +020032 struct process * tmp = list_of_processes;
33
34 signal(SIGALRM,SIG_DFL);
35 while(tmp) {
36 struct opt_p_t * tmp2 = opt_p;
37 while(tmp2) {
38 if (tmp->pid == tmp2->pid) {
39 tmp = tmp->next;
40 if (!tmp) {
41 return;
42 }
43 break;
44 }
45 tmp2 = tmp2->next;
46 }
Juan Cespedescac15c32003-01-31 18:58:58 +010047 debug(2,"Sending SIGSTOP to process %u\n",tmp->pid);
Juan Cespedes28f60191998-04-12 00:04:39 +020048 kill(tmp->pid, SIGSTOP);
49 tmp = tmp->next;
50 }
51}
52
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010053static void
54signal_exit(int sig) {
Juan Cespedes28f60191998-04-12 00:04:39 +020055 exiting=1;
Juan Cespedescac15c32003-01-31 18:58:58 +010056 debug(1,"Received interrupt signal; exiting...");
Juan Cespedes28f60191998-04-12 00:04:39 +020057 signal(SIGINT,SIG_IGN);
58 signal(SIGTERM,SIG_IGN);
59 signal(SIGALRM,signal_alarm);
60 if (opt_p) {
61 struct opt_p_t * tmp = opt_p;
62 while(tmp) {
Juan Cespedescac15c32003-01-31 18:58:58 +010063 debug(2,"Sending SIGSTOP to process %u\n",tmp->pid);
Juan Cespedes28f60191998-04-12 00:04:39 +020064 kill(tmp->pid, SIGSTOP);
65 tmp = tmp->next;
66 }
67 }
68 alarm(1);
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020069}
70
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010071static void
72normal_exit(void) {
Juan Cespedes28f60191998-04-12 00:04:39 +020073 output_line(0,0);
Juan Cespedesd65efa32003-02-03 00:22:30 +010074 if (opt_c) {
75 summary();
76 }
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020077}
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020078
Juan Cespedesa0ccf392003-02-01 19:02:37 +010079static void
80guess_cols(void) {
81 struct winsize ws;
82 char * c;
83
84 opt_a = DEFAULT_ACOLUMN;
85 c = getenv("COLUMNS");
86 if (c && *c) {
87 char * endptr;
88 int cols;
89 cols = strtol(c, &endptr, 0);
90 if (cols>0 && !*endptr) {
91 opt_a = cols * 5/8;
92 }
93 } else if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col>0) {
94 opt_a = ws.ws_col * 5/8;
95 }
96}
97
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010098int
99main(int argc, char **argv) {
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +0200100 struct opt_p_t * opt_p_tmp;
Juan Cespedesf1bfe202002-03-27 00:22:23 +0100101 char * home;
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +0200102
103 atexit(normal_exit);
104 signal(SIGINT,signal_exit); /* Detach processes when interrupted */
105 signal(SIGTERM,signal_exit); /* ... or killed */
106
Juan Cespedesa0ccf392003-02-01 19:02:37 +0100107 guess_cols();
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +0200108 argv = process_options(argc, argv);
Juan Cespedesf1bfe202002-03-27 00:22:23 +0100109 read_config_file(SYSCONFDIR "/ltrace.conf");
110 home = getenv("HOME");
111 if (home) {
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +0200112 char path[PATH_MAX];
Juan Cespedesf1bfe202002-03-27 00:22:23 +0100113 if (strlen(home) > PATH_MAX-15) {
114 fprintf(stderr, "Error: $HOME too long\n");
115 exit(1);
116 }
117 strcpy(path, getenv("HOME"));
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +0200118 strcat(path, "/.ltrace.conf");
119 read_config_file(path);
120 }
Juan Cespedescac15c32003-01-31 18:58:58 +0100121 if (opt_e) {
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +0200122 struct opt_e_t * tmp = opt_e;
123 while(tmp) {
Juan Cespedescac15c32003-01-31 18:58:58 +0100124 debug(1,"Option -e: %s\n", tmp->name);
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +0200125 tmp = tmp->next;
126 }
127 }
128 if (command) {
129 execute_program(open_program(command), argv);
130 }
131 opt_p_tmp = opt_p;
132 while (opt_p_tmp) {
133 open_pid(opt_p_tmp->pid, 1);
134 opt_p_tmp = opt_p_tmp->next;
135 }
136 while(1) {
137 process_event(wait_for_something());
138 }
139}