#if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include "ltrace.h" #include "output.h" #include "read_config_file.h" #include "options.h" #include "debug.h" char *command = NULL; Process *list_of_processes = NULL; int exiting = 0; /* =1 if a SIGINT or SIGTERM has been received */ static void signal_alarm(int sig) { Process *tmp = list_of_processes; signal(SIGALRM, SIG_DFL); while (tmp) { struct opt_p_t *tmp2 = opt_p; while (tmp2) { if (tmp->pid == tmp2->pid) { tmp = tmp->next; if (!tmp) { return; } tmp2 = opt_p; continue; } tmp2 = tmp2->next; } debug(2, "Sending SIGSTOP to process %u\n", tmp->pid); kill(tmp->pid, SIGSTOP); tmp = tmp->next; } } static void signal_exit(int sig) { exiting = 1; debug(1, "Received interrupt signal; exiting..."); signal(SIGINT, SIG_IGN); signal(SIGTERM, SIG_IGN); signal(SIGALRM, signal_alarm); if (opt_p) { struct opt_p_t *tmp = opt_p; while (tmp) { debug(2, "Sending SIGSTOP to process %u\n", tmp->pid); kill(tmp->pid, SIGSTOP); tmp = tmp->next; } } alarm(1); } static void normal_exit(void) { output_line(0, 0); if (options.summary) { show_summary(); } if (options.output) { fclose(options.output); options.output = NULL; } } int main(int argc, char **argv) { struct opt_p_t *opt_p_tmp; atexit(normal_exit); signal(SIGINT, signal_exit); /* Detach processes when interrupted */ signal(SIGTERM, signal_exit); /* ... or killed */ argv = process_options(argc, argv); while (opt_F) { /* If filename begins with ~, expand it to the user's home */ /* directory. This does not correctly handle ~yoda, but that */ /* isn't as bad as it seems because the shell will normally */ /* be doing the expansion for us; only the hardcoded */ /* ~/.ltrace.conf should ever use this code. */ if (opt_F->filename[0] == '~') { char path[PATH_MAX]; char *home_dir = getenv("HOME"); if (home_dir) { strncpy(path, home_dir, PATH_MAX - 1); path[PATH_MAX - 1] = '\0'; strncat(path, opt_F->filename + 1, PATH_MAX - strlen(path) - 1); read_config_file(path); } } else { read_config_file(opt_F->filename); } opt_F = opt_F->next; } if (opt_e) { struct opt_e_t *tmp = opt_e; while (tmp) { debug(1, "Option -e: %s\n", tmp->name); tmp = tmp->next; } } if (command) { execute_program(open_program(command, 0), argv); } opt_p_tmp = opt_p; while (opt_p_tmp) { open_pid(opt_p_tmp->pid, 1); opt_p_tmp = opt_p_tmp->next; } while (1) { process_event(next_event()); } }