libltrace.c revision f728123bd75a65a6a1536e198c3c30719e494e71
1#if HAVE_CONFIG_H 2#include "config.h" 3#endif 4 5#include <stdio.h> 6#include <stdlib.h> 7#include <unistd.h> 8#include <string.h> 9#include <errno.h> 10#include <sys/param.h> 11#include <signal.h> 12#include <sys/wait.h> 13 14#include "common.h" 15#include "output.h" 16#include "read_config_file.h" 17#include "options.h" 18#include "debug.h" 19 20char *command = NULL; 21Process *list_of_processes = NULL; 22 23int exiting = 0; /* =1 if a SIGINT or SIGTERM has been received */ 24 25static void 26signal_alarm(int sig) { 27 Process *tmp = list_of_processes; 28 29 signal(SIGALRM, SIG_DFL); 30 while (tmp) { 31 struct opt_p_t *tmp2 = opt_p; 32 while (tmp2) { 33 if (tmp->pid == tmp2->pid) { 34 tmp = tmp->next; 35 if (!tmp) { 36 return; 37 } 38 tmp2 = opt_p; 39 continue; 40 } 41 tmp2 = tmp2->next; 42 } 43 debug(2, "Sending SIGSTOP to process %u\n", tmp->pid); 44 kill(tmp->pid, SIGSTOP); 45 tmp = tmp->next; 46 } 47} 48 49static void 50signal_exit(int sig) { 51 exiting = 1; 52 debug(1, "Received interrupt signal; exiting..."); 53 signal(SIGINT, SIG_IGN); 54 signal(SIGTERM, SIG_IGN); 55 signal(SIGALRM, signal_alarm); 56 if (opt_p) { 57 struct opt_p_t *tmp = opt_p; 58 while (tmp) { 59 debug(2, "Sending SIGSTOP to process %u\n", tmp->pid); 60 kill(tmp->pid, SIGSTOP); 61 tmp = tmp->next; 62 } 63 } 64 alarm(1); 65} 66 67static void 68normal_exit(void) { 69 output_line(0, 0); 70 if (options.summary) { 71 show_summary(); 72 } 73 if (options.output) { 74 fclose(options.output); 75 options.output = NULL; 76 } 77} 78 79void 80ltrace_init(int argc, char **argv) { 81 struct opt_p_t *opt_p_tmp; 82 83 atexit(normal_exit); 84 signal(SIGINT, signal_exit); /* Detach processes when interrupted */ 85 signal(SIGTERM, signal_exit); /* ... or killed */ 86 87 argv = process_options(argc, argv); 88 while (opt_F) { 89 /* If filename begins with ~, expand it to the user's home */ 90 /* directory. This does not correctly handle ~yoda, but that */ 91 /* isn't as bad as it seems because the shell will normally */ 92 /* be doing the expansion for us; only the hardcoded */ 93 /* ~/.ltrace.conf should ever use this code. */ 94 if (opt_F->filename[0] == '~') { 95 char path[PATH_MAX]; 96 char *home_dir = getenv("HOME"); 97 if (home_dir) { 98 strncpy(path, home_dir, PATH_MAX - 1); 99 path[PATH_MAX - 1] = '\0'; 100 strncat(path, opt_F->filename + 1, 101 PATH_MAX - strlen(path) - 1); 102 read_config_file(path); 103 } 104 } else { 105 read_config_file(opt_F->filename); 106 } 107 opt_F = opt_F->next; 108 } 109 if (opt_e) { 110 struct opt_e_t *tmp = opt_e; 111 while (tmp) { 112 debug(1, "Option -e: %s\n", tmp->name); 113 tmp = tmp->next; 114 } 115 } 116 if (command) { 117 execute_program(open_program(command, 0), argv); 118 } 119 opt_p_tmp = opt_p; 120 while (opt_p_tmp) { 121 open_pid(opt_p_tmp->pid, 1); 122 opt_p_tmp = opt_p_tmp->next; 123 } 124} 125 126void 127ltrace_main(void) { 128 while (1) { 129 process_event(next_event()); 130 } 131} 132