diff options
author | Juan Cespedes <cespedes@debian.org> | 2009-06-25 16:11:21 +0200 |
---|---|---|
committer | Juan Cespedes <cespedes@debian.org> | 2009-06-25 16:11:21 +0200 |
commit | f728123bd75a65a6a1536e198c3c30719e494e71 (patch) | |
tree | 21f66082275987a9b24fbc776fa607c6113acf0e /libltrace.c | |
parent | 3df476b28e4a9cdb43cf29fff8e89481310eb30d (diff) | |
download | ltrace-f728123bd75a65a6a1536e198c3c30719e494e71.tar.gz |
Re-organize file names
Diffstat (limited to 'libltrace.c')
-rw-r--r-- | libltrace.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/libltrace.c b/libltrace.c new file mode 100644 index 0000000..381cfa2 --- /dev/null +++ b/libltrace.c @@ -0,0 +1,131 @@ +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <sys/param.h> +#include <signal.h> +#include <sys/wait.h> + +#include "common.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; + } +} + +void +ltrace_init(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; + } +} + +void +ltrace_main(void) { + while (1) { + process_event(next_event()); + } +} |