Version 0.2.9

* Bug#20616 wasn't completely fixed; it didn't work with some programs (Fixed)
* Stopping ltrace with ^C DIDN'T WORK if -p option is not used!!  (Fixed)
* Option -f caused program to segfault; fixed
* Fixed nasty bug about executing set[ug]id binaries:
  When executing a program fails, don't left the program STOPPED.
* Make ltrace work with all setuid and setgid binaries when invoked as root
diff --git a/ltrace.c b/ltrace.c
index 1ce1108..bb7eef8 100644
--- a/ltrace.c
+++ b/ltrace.c
@@ -5,21 +5,27 @@
 #include <errno.h>
 #include <sys/param.h>
 #include <signal.h>
+#include <sys/wait.h>
 
 #include "ltrace.h"
-#include "elf.h"
 #include "output.h"
-#include "config_file.h"
+#include "read_config_file.h"
 #include "options.h"
 
 char * command = NULL;
 struct process * list_of_processes = NULL;
 
+int exiting=0;				/* =1 if a SIGINT or SIGTERM has been received */
+
 static void normal_exit(void);
 static void signal_exit(int);
+static pid_t my_pid;
 
 int main(int argc, char **argv)
 {
+	struct opt_p_t * opt_p_tmp;
+
+	my_pid = getpid();
 	atexit(normal_exit);
 	signal(SIGINT,signal_exit);	/* Detach processes when interrupted */
 	signal(SIGTERM,signal_exit);	/*  ... or killed */
@@ -32,32 +38,67 @@
 		strcat(path, "/.ltrace.conf");
 		read_config_file(path);
 	}
-	while (opt_p) {
-		open_pid(opt_p->pid, 1);
-		opt_p = opt_p->next;
-	}
 	if (command) {
 		execute_program(open_program(command), 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());
 	}
 }
 
+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;
+		}
+		if (opt_d>1) {
+			output_line(0,"Sending SIGSTOP to process %u\n",tmp->pid);
+		}
+		kill(tmp->pid, SIGSTOP);
+		tmp = tmp->next;
+	}
+}
+
 static void signal_exit(int sig)
 {
-	exit(2);
+	exiting=1;
+	if (opt_d) {
+		output_line(0,"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) {
+			if (opt_d>1) {
+				output_line(0,"Sending SIGSTOP to process %u\n",tmp->pid);
+			}
+			kill(tmp->pid, SIGSTOP);
+			tmp = tmp->next;
+		}
+	}
+	alarm(1);
 }
 
 static void normal_exit(void)
 {
-	struct process * tmp = list_of_processes;
-
-	while(tmp) {
-		kill(tmp->pid, SIGSTOP);
-		disable_all_breakpoints(tmp);
-		continue_process(tmp->pid);
-		untrace_pid(tmp->pid);
-		tmp = tmp->next;
-	}
+	output_line(0,0);
 }