aboutsummaryrefslogtreecommitdiff
path: root/libltrace.c
diff options
context:
space:
mode:
authorJuan Cespedes <cespedes@debian.org>2009-06-25 16:11:21 +0200
committerJuan Cespedes <cespedes@debian.org>2009-06-25 16:11:21 +0200
commitf728123bd75a65a6a1536e198c3c30719e494e71 (patch)
tree21f66082275987a9b24fbc776fa607c6113acf0e /libltrace.c
parent3df476b28e4a9cdb43cf29fff8e89481310eb30d (diff)
downloadltrace-f728123bd75a65a6a1536e198c3c30719e494e71.tar.gz
Re-organize file names
Diffstat (limited to 'libltrace.c')
-rw-r--r--libltrace.c131
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());
+ }
+}