Added different callback handlers for each event
diff --git a/handle_event.c b/handle_event.c
index 18f64c6..48b9945 100644
--- a/handle_event.c
+++ b/handle_event.c
@@ -34,13 +34,88 @@
 				   struct library_symbol *sym);
 static void callstack_pop(Process *proc);
 
+static char * shortsignal(Process *proc, int signum);
+static char * sysname(Process *proc, int sysnum);
+static char * arch_sysname(Process *proc, int sysnum);
+
+void
+handle_event(Event *event) {
+	debug(DEBUG_FUNCTION, "handle_event(pid=%d, type=%d)", event->proc ? event->proc->pid : -1, event->type);
+	switch (event->type) {
+	case EVENT_NONE:
+		debug(1, "event: none");
+		return;
+	case EVENT_SIGNAL:
+		debug(1, "event: signal (%s [%d])",
+		      shortsignal(event->proc, event->e_un.signum),
+		      event->e_un.signum);
+		handle_signal(event);
+		return;
+	case EVENT_EXIT:
+		debug(1, "event: exit (%d)", event->e_un.ret_val);
+		handle_exit(event);
+		return;
+	case EVENT_EXIT_SIGNAL:
+		debug(1, "event: exit signal (%s [%d])",
+		      shortsignal(event->proc, event->e_un.signum),
+		      event->e_un.signum);
+		handle_exit_signal(event);
+		return;
+	case EVENT_SYSCALL:
+		debug(1, "event: syscall (%s [%d])",
+		      sysname(event->proc, event->e_un.sysnum),
+		      event->e_un.sysnum);
+		handle_syscall(event);
+		return;
+	case EVENT_SYSRET:
+		debug(1, "event: sysret (%s [%d])",
+		      sysname(event->proc, event->e_un.sysnum),
+		      event->e_un.sysnum);
+		handle_sysret(event);
+		return;
+	case EVENT_ARCH_SYSCALL:
+		debug(1, "event: arch_syscall (%s [%d])",
+				arch_sysname(event->proc, event->e_un.sysnum),
+				event->e_un.sysnum);
+		handle_arch_syscall(event);
+		return;
+	case EVENT_ARCH_SYSRET:
+		debug(1, "event: arch_sysret (%s [%d])",
+				arch_sysname(event->proc, event->e_un.sysnum),
+				event->e_un.sysnum);
+		handle_arch_sysret(event);
+		return;
+	case EVENT_CLONE:
+		debug(1, "event: clone (%u)", event->e_un.newpid);
+		handle_clone(event);
+		return;
+	case EVENT_EXEC:
+		debug(1, "event: exec()");
+		handle_exec(event);
+		return;
+	case EVENT_BREAKPOINT:
+		debug(1, "event: breakpoint");
+		handle_breakpoint(event);
+		return;
+	case EVENT_NEW:
+		debug(1, "event: new process");
+		handle_new(event);
+		return;
+	default:
+		fprintf(stderr, "Error! unknown event?\n");
+		exit(1);
+	}
+}
+
 /* TODO */
-void * address_clone(void * addr) {
+static void *
+address_clone(void * addr) {
 	debug(DEBUG_FUNCTION, "address_clone(%p)", addr);
 	return addr;
 }
 
-void * breakpoint_clone(void * bp) {
+static void *
+breakpoint_clone(void * bp) {
 	Breakpoint * b;
 	debug(DEBUG_FUNCTION, "breakpoint_clone(%p)", bp);
 	b = malloc(sizeof(Breakpoint));
@@ -247,75 +322,6 @@
 	}
 }
 
-void
-handle_event(Event *event) {
-	debug(DEBUG_FUNCTION, "handle_event(pid=%d, type=%d)", event->proc ? event->proc->pid : -1, event->type);
-	switch (event->type) {
-	case EVENT_NONE:
-		debug(1, "event: none");
-		return;
-	case EVENT_SIGNAL:
-		debug(1, "event: signal (%s [%d])",
-		      shortsignal(event->proc, event->e_un.signum),
-		      event->e_un.signum);
-		handle_signal(event);
-		return;
-	case EVENT_EXIT:
-		debug(1, "event: exit (%d)", event->e_un.ret_val);
-		handle_exit(event);
-		return;
-	case EVENT_EXIT_SIGNAL:
-		debug(1, "event: exit signal (%s [%d])",
-		      shortsignal(event->proc, event->e_un.signum),
-		      event->e_un.signum);
-		handle_exit_signal(event);
-		return;
-	case EVENT_SYSCALL:
-		debug(1, "event: syscall (%s [%d])",
-		      sysname(event->proc, event->e_un.sysnum),
-		      event->e_un.sysnum);
-		handle_syscall(event);
-		return;
-	case EVENT_SYSRET:
-		debug(1, "event: sysret (%s [%d])",
-		      sysname(event->proc, event->e_un.sysnum),
-		      event->e_un.sysnum);
-		handle_sysret(event);
-		return;
-	case EVENT_ARCH_SYSCALL:
-		debug(1, "event: arch_syscall (%s [%d])",
-				arch_sysname(event->proc, event->e_un.sysnum),
-				event->e_un.sysnum);
-		handle_arch_syscall(event);
-		return;
-	case EVENT_ARCH_SYSRET:
-		debug(1, "event: arch_sysret (%s [%d])",
-				arch_sysname(event->proc, event->e_un.sysnum),
-				event->e_un.sysnum);
-		handle_arch_sysret(event);
-		return;
-	case EVENT_CLONE:
-		debug(1, "event: clone (%u)", event->e_un.newpid);
-		handle_clone(event);
-		return;
-	case EVENT_EXEC:
-		debug(1, "event: exec()");
-		handle_exec(event);
-		return;
-	case EVENT_BREAKPOINT:
-		debug(1, "event: breakpoint");
-		handle_breakpoint(event);
-		return;
-	case EVENT_NEW:
-		debug(1, "event: new process");
-		handle_new(event);
-		return;
-	default:
-		fprintf(stderr, "Error! unknown event?\n");
-		exit(1);
-	}
-}
-
 static void
 handle_signal(Event *event) {
 	debug(DEBUG_FUNCTION, "handle_signal(pid=%d, signum=%d)", event->proc->pid, event->e_un.signum);
diff --git a/libltrace.c b/libltrace.c
index 731ead2..6827257 100644
--- a/libltrace.c
+++ b/libltrace.c
@@ -119,34 +119,38 @@
 	}
 }
 
-static int num_ltrace_callbacks = 0;
-static void (**ltrace_callbacks)(Event *) = NULL;
+static int num_ltrace_callbacks[EVENT_MAX];
+static callback_func * ltrace_callbacks[EVENT_MAX];
 
 void
-ltrace_add_callback(void (*func)(Event *)) {
-	ltrace_callbacks = realloc(ltrace_callbacks, (num_ltrace_callbacks+1)*sizeof(*ltrace_callbacks));
-	ltrace_callbacks[num_ltrace_callbacks++] = func;
+ltrace_add_callback(callback_func func, Event_type type) {
+	ltrace_callbacks[type] = realloc(ltrace_callbacks[type], (num_ltrace_callbacks[type]+1)*sizeof(callback_func));
+	ltrace_callbacks[type][num_ltrace_callbacks[type]++] = func;
+}
 
-	{
-		int i;
-
-		printf("*** Added callback\n");
-		printf("\tThere are %d callbacks:\n", num_ltrace_callbacks);
-		for (i=0; i<num_ltrace_callbacks; i++) {
-			printf("\t\t%10p\n", ltrace_callbacks[i]);
-		}
+static void
+dispatch_callbacks(Event * ev) {
+	int i;
+	/* Ignoring case 1: signal into a dying tracer */
+	if (ev->type==EVENT_SIGNAL && 
+			exiting && ev->e_un.signum == SIGSTOP) {
+		return;
+	}
+	/* Ignoring case 2: process being born before a clone event */
+	if (ev->proc && ev->proc->state == STATE_IGNORED) {
+		return;
+	}
+	for (i=0; i<num_ltrace_callbacks[ev->type]; i++) {
+		ltrace_callbacks[ev->type][i](ev);
 	}
 }
 
 void
 ltrace_main(void) {
-	int i;
 	Event * ev;
 	while (1) {
 		ev = next_event();
-		for (i=0; i<num_ltrace_callbacks; i++) {
-			ltrace_callbacks[i](ev);
-		}
+		dispatch_callbacks(ev);
 		handle_event(ev);
 	}
 }
diff --git a/ltrace.h b/ltrace.h
index 9ba16a6..f918d8a 100644
--- a/ltrace.h
+++ b/ltrace.h
@@ -1,9 +1,6 @@
-typedef struct Process Process;
-typedef struct Event Event;
-struct Event {
-	Process *proc;
-	enum {
-		EVENT_NONE,
+typedef enum Event_type Event_type;
+enum Event_type {
+		EVENT_NONE=0,
 		EVENT_SIGNAL,
 		EVENT_EXIT,
 		EVENT_EXIT_SIGNAL,
@@ -14,17 +11,26 @@
 		EVENT_CLONE,
 		EVENT_EXEC,
 		EVENT_BREAKPOINT,
-		EVENT_NEW       /* in this case, proc is NULL */
-	} type;
+		EVENT_NEW,        /* in this case, proc is NULL */
+		EVENT_MAX
+};
+
+typedef struct Process Process;
+typedef struct Event Event;
+struct Event {
+	Process * proc;
+	Event_type type;
 	union {
-		int ret_val;    /* EVENT_EXIT */
-		int signum;     /* EVENT_SIGNAL, EVENT_EXIT_SIGNAL */
-		int sysnum;     /* EVENT_SYSCALL, EVENT_SYSRET */
-		void *brk_addr; /* EVENT_BREAKPOINT */
-		int newpid;     /* EVENT_CLONE, EVENT_NEW */
+		int ret_val;     /* EVENT_EXIT */
+		int signum;      /* EVENT_SIGNAL, EVENT_EXIT_SIGNAL */
+		int sysnum;      /* EVENT_SYSCALL, EVENT_SYSRET */
+		void * brk_addr; /* EVENT_BREAKPOINT */
+		int newpid;      /* EVENT_CLONE, EVENT_NEW */
 	} e_un;
 };
 
+typedef void (*callback_func) (Event *);
+
 extern void ltrace_init(int argc, char **argv);
-extern void ltrace_add_callback(void (*func)(Event *));
+extern void ltrace_add_callback(callback_func f, Event_type type);
 extern void ltrace_main(void);
diff --git a/main.c b/main.c
index 04f6a30..bd443cf 100644
--- a/main.c
+++ b/main.c
@@ -4,18 +4,34 @@
 #include "ltrace.h"
 
 /*
+static int count_call =0;
+static int count_ret  =0;
+
 static void
-callback(Event * ev) {
-	printf("\n\tcallback(ev->type=%d)\n", ev->type);
+callback_call(Event * ev) {
+	count_call ++;
+}
+static void
+callback_ret(Event * ev) {
+	count_ret ++;
+}
+
+static void
+endcallback(Event *ev) {
+	printf("%d calls\n%d rets\n",count_call, count_ret);
 }
 */
 
 int
 main(int argc, char *argv[]) {
 	ltrace_init(argc, argv);
+
 /*
-	ltrace_add_callback(callback);
+	ltrace_add_callback(callback_call, EVENT_SYSCALL);
+	ltrace_add_callback(callback_ret, EVENT_SYSRET);
+	ltrace_add_callback(endcallback, EVENT_EXIT);
 */
+
 	ltrace_main();
 	return 0;
 }
diff --git a/output.h b/output.h
index c882c0f..c58577a 100644
--- a/output.h
+++ b/output.h
@@ -1,4 +1,3 @@
 void output_line(Process *proc, char *fmt, ...);
-
 void output_left(enum tof type, Process *proc, char *function_name);
 void output_right(enum tof type, Process *proc, char *function_name);
diff --git a/sysdeps/linux-gnu/breakpoint.c b/sysdeps/linux-gnu/breakpoint.c
index df6e52c..ebd8d8a 100644
--- a/sysdeps/linux-gnu/breakpoint.c
+++ b/sysdeps/linux-gnu/breakpoint.c
@@ -4,6 +4,7 @@
 
 #include <sys/ptrace.h>
 #include <string.h>
+
 #include "common.h"
 
 static unsigned char break_insn[] = BREAKPOINT_VALUE;
diff --git a/sysdeps/linux-gnu/events.c b/sysdeps/linux-gnu/events.c
index 4ad6f88..3e681a8 100644
--- a/sysdeps/linux-gnu/events.c
+++ b/sysdeps/linux-gnu/events.c
@@ -60,7 +60,7 @@
 	}
 	if (opt_i) {
 		event.proc->instruction_pointer =
-		    get_instruction_pointer(event.proc);
+			get_instruction_pointer(event.proc);
 	}
 	switch (syscall_p(event.proc, status, &tmp)) {
 		case 1:
diff --git a/sysdeps/linux-gnu/ppc/regs.c b/sysdeps/linux-gnu/ppc/regs.c
index 714d57f..67df5c9 100644
--- a/sysdeps/linux-gnu/ppc/regs.c
+++ b/sysdeps/linux-gnu/ppc/regs.c
@@ -18,19 +18,17 @@
 
 void *
 get_instruction_pointer(Process *proc) {
-	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long) * PT_NIP,
-			      0);
+	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_NIP, 0);
 }
 
 void
 set_instruction_pointer(Process *proc, void *addr) {
-	ptrace(PTRACE_POKEUSER, proc->pid, sizeof(long) * PT_NIP, addr);
+	ptrace(PTRACE_POKEUSER, proc->pid, sizeof(long)*PT_NIP, addr);
 }
 
 void *
 get_stack_pointer(Process *proc) {
-	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long) * PT_R1,
-			      0);
+	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_R1, 0);
 }
 
 void *