blob: 78f74da04519ee0fba9c8b07eff3960c9187152e [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 Cespedes1c2be911997-06-09 01:12:01 +020013
Juan Cespedes5e01f651998-03-08 22:31:44 +010014#include "ltrace.h"
Juan Cespedes3268a161997-08-25 16:45:22 +020015#include "output.h"
Juan Cespedes28f60191998-04-12 00:04:39 +020016#include "read_config_file.h"
Juan Cespedes5e01f651998-03-08 22:31:44 +010017#include "options.h"
Juan Cespedes96935a91997-08-09 23:45:39 +020018
Juan Cespedesf1bfe202002-03-27 00:22:23 +010019#ifndef SYSCONFDIR
20#define SYSCONFDIR "/etc"
21#endif
22
Juan Cespedes1fe93d51998-03-13 00:29:21 +010023char * command = NULL;
Juan Cespedes5e01f651998-03-08 22:31:44 +010024struct process * list_of_processes = NULL;
Juan Cespedes24c82531997-06-25 00:02:58 +020025
Juan Cespedes28f60191998-04-12 00:04:39 +020026int exiting=0; /* =1 if a SIGINT or SIGTERM has been received */
27
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010028static void
29signal_alarm(int sig) {
Juan Cespedes28f60191998-04-12 00:04:39 +020030 struct process * tmp = list_of_processes;
31
32 signal(SIGALRM,SIG_DFL);
33 while(tmp) {
34 struct opt_p_t * tmp2 = opt_p;
35 while(tmp2) {
36 if (tmp->pid == tmp2->pid) {
37 tmp = tmp->next;
38 if (!tmp) {
39 return;
40 }
41 break;
42 }
43 tmp2 = tmp2->next;
44 }
45 if (opt_d>1) {
46 output_line(0,"Sending SIGSTOP to process %u\n",tmp->pid);
47 }
48 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;
56 if (opt_d) {
57 output_line(0,"Received interrupt signal; exiting...");
58 }
59 signal(SIGINT,SIG_IGN);
60 signal(SIGTERM,SIG_IGN);
61 signal(SIGALRM,signal_alarm);
62 if (opt_p) {
63 struct opt_p_t * tmp = opt_p;
64 while(tmp) {
65 if (opt_d>1) {
66 output_line(0,"Sending SIGSTOP to process %u\n",tmp->pid);
67 }
68 kill(tmp->pid, SIGSTOP);
69 tmp = tmp->next;
70 }
71 }
72 alarm(1);
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020073}
74
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010075static void
76normal_exit(void) {
Juan Cespedes28f60191998-04-12 00:04:39 +020077 output_line(0,0);
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020078}
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020079
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010080int
81main(int argc, char **argv) {
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020082 struct opt_p_t * opt_p_tmp;
Juan Cespedesf1bfe202002-03-27 00:22:23 +010083 char * home;
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020084
85 atexit(normal_exit);
86 signal(SIGINT,signal_exit); /* Detach processes when interrupted */
87 signal(SIGTERM,signal_exit); /* ... or killed */
88
89 argv = process_options(argc, argv);
Juan Cespedesf1bfe202002-03-27 00:22:23 +010090 read_config_file(SYSCONFDIR "/ltrace.conf");
91 home = getenv("HOME");
92 if (home) {
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020093 char path[PATH_MAX];
Juan Cespedesf1bfe202002-03-27 00:22:23 +010094 if (strlen(home) > PATH_MAX-15) {
95 fprintf(stderr, "Error: $HOME too long\n");
96 exit(1);
97 }
98 strcpy(path, getenv("HOME"));
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020099 strcat(path, "/.ltrace.conf");
100 read_config_file(path);
101 }
102 if (opt_d && opt_e) {
103 struct opt_e_t * tmp = opt_e;
104 while(tmp) {
105 printf("Option -e: %s\n", tmp->name);
106 tmp = tmp->next;
107 }
108 }
109 if (command) {
110 execute_program(open_program(command), argv);
111 }
112 opt_p_tmp = opt_p;
113 while (opt_p_tmp) {
114 open_pid(opt_p_tmp->pid, 1);
115 opt_p_tmp = opt_p_tmp->next;
116 }
117 while(1) {
118 process_event(wait_for_something());
119 }
120}