1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
#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 <sys/ioctl.h>
#include "ltrace.h"
#include "output.h"
#include "read_config_file.h"
#include "options.h"
#include "debug.h"
#ifndef SYSCONFDIR
#define SYSCONFDIR "/etc"
#endif
char *command = NULL;
struct process *list_of_processes = NULL;
int exiting = 0; /* =1 if a SIGINT or SIGTERM has been received */
static void signal_alarm(int sig)
{
struct 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;
}
break;
}
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...");
if (opt_o) {
fclose(output);
}
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 (opt_c) {
show_summary();
}
if (opt_o) {
fclose(output);
}
}
static void guess_cols(void)
{
struct winsize ws;
char *c;
opt_a = DEFAULT_ACOLUMN;
c = getenv("COLUMNS");
if (c && *c) {
char *endptr;
int cols;
cols = strtol(c, &endptr, 0);
if (cols > 0 && !*endptr) {
opt_a = cols * 5 / 8;
}
} else if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col > 0) {
opt_a = ws.ws_col * 5 / 8;
}
}
int main(int argc, char **argv)
{
struct opt_p_t *opt_p_tmp;
char *home;
atexit(normal_exit);
signal(SIGINT, signal_exit); /* Detach processes when interrupted */
signal(SIGTERM, signal_exit); /* ... or killed */
guess_cols();
argv = process_options(argc, argv);
read_config_file(SYSCONFDIR "/ltrace.conf");
home = getenv("HOME");
if (home) {
char path[PATH_MAX];
if (strlen(home) > PATH_MAX - 15) {
fprintf(stderr, "Error: $HOME too long\n");
exit(1);
}
strcpy(path, getenv("HOME"));
strcat(path, "/.ltrace.conf");
read_config_file(path);
}
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(wait_for_something());
}
}
|