Adding signal handler to allow clean exit of PCU

The signal handler will end the main loop, so clean exit is performed.

The allocated memory is dumped in order to detect memory leaks.

All talloc functions use tall_pcu_ctx context instead of NULL, to track
memory leaks.
diff --git a/src/openbts_sock.cpp b/src/openbts_sock.cpp
index cbf7adc..1f1e904 100644
--- a/src/openbts_sock.cpp
+++ b/src/openbts_sock.cpp
@@ -35,6 +35,8 @@
 #include <pcuif_proto.h>
 }
 
+extern void *tall_pcu_ctx;
+
 struct femtol1_hdl {
 	struct gsm_time gsm_time;
 	uint32_t hLayer1;			/* handle to the L1 instance in the DSP */
@@ -142,7 +144,7 @@
 	int rc;
 
 	/* allocate new femtol1_handle */
-	fl1h = talloc_zero(NULL, struct femtol1_hdl);
+	fl1h = talloc_zero(tall_pcu_ctx, struct femtol1_hdl);
 	INIT_LLIST_HEAD(&fl1h->wlc_list);
 
 	l1fh->fl1h = fl1h;
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index fd8b3c3..d0f2e32 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -37,6 +37,8 @@
 #include <gprs_bssgp_pcu.h>
 #include <pcuif_proto.h>
 
+extern void *tall_pcu_ctx;
+
 // Variable for storage current FN.
 int frame_number;
 
diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp
index 2a01b9b..2c6d763 100644
--- a/src/pcu_main.cpp
+++ b/src/pcu_main.cpp
@@ -25,6 +25,7 @@
 #include <gprs_debug.h>
 #include <unistd.h>
 #include <getopt.h>
+#include <signal.h>
 extern "C" {
 #include "pcu_vty.h"
 #include <osmocom/vty/telnet_interface.h>
@@ -38,6 +39,7 @@
 static const char *config_file = "osmo-pcu.cfg";
 extern struct vty_app_info pcu_vty_info;
 void *tall_pcu_ctx;
+static int quit = 0;
 
 static void print_help()
 {
@@ -93,6 +95,39 @@
 	}
 }
 
+void sighandler(int sigset)
+{
+	if (sigset == SIGHUP || sigset == SIGPIPE)
+		return;
+
+	fprintf(stderr, "Signal %d received.\n", sigset);
+
+	switch (sigset) {
+	case SIGINT:
+		/* If another signal is received afterwards, the program
+		 * is terminated without finishing shutdown process.
+		 */
+		signal(SIGINT, SIG_DFL);
+		signal(SIGHUP, SIG_DFL);
+		signal(SIGTERM, SIG_DFL);
+		signal(SIGPIPE, SIG_DFL);
+		signal(SIGABRT, SIG_DFL);
+		signal(SIGUSR1, SIG_DFL);
+		signal(SIGUSR2, SIG_DFL);
+
+		quit = 1;
+		break;
+	case SIGABRT:
+		/* in case of abort, we want to obtain a talloc report
+		 * and then return to the caller, who will abort the process
+		 */
+	case SIGUSR1:
+	case SIGUSR2:
+		talloc_report_full(tall_pcu_ctx, stderr);
+		break;
+	}
+}
+
 int main(int argc, char *argv[])
 {
 	struct gprs_rlcmac_bts *bts;
@@ -118,6 +153,8 @@
 	bts->n3103 = 4;
 	bts->n3105 = 8;
 
+	msgb_set_talloc_ctx(tall_pcu_ctx);
+
 	osmo_init_logging(&gprs_log_info);
 
 	vty_init(&pcu_vty_info);
@@ -151,8 +188,15 @@
 	if (rc < 0)
 		return rc;
 
-	while (1) 
-	{
+	signal(SIGINT, sighandler);
+	signal(SIGHUP, sighandler);
+	signal(SIGTERM, sighandler);
+	signal(SIGPIPE, sighandler);
+	signal(SIGABRT, sighandler);
+	signal(SIGUSR1, sighandler);
+	signal(SIGUSR2, sighandler);
+
+	while (!quit) {
 		osmo_gsm_timers_check();
 		osmo_gsm_timers_prepare();
 		osmo_gsm_timers_update();
@@ -160,8 +204,13 @@
 		osmo_select_main(0);
 	}
 
+	telnet_exit();
+
 	pcu_l1if_close();
+
 	talloc_free(gprs_rlcmac_bts);
+
+	talloc_report_full(tall_pcu_ctx, stderr);
 	talloc_free(tall_pcu_ctx);
 
 	return 0;
diff --git a/src/sysmo_sock.cpp b/src/sysmo_sock.cpp
index 8d83ca2..390f3f6 100644
--- a/src/sysmo_sock.cpp
+++ b/src/sysmo_sock.cpp
@@ -37,6 +37,7 @@
 #include <gprs_bssgp_pcu.h>
 #include <pcuif_proto.h>
 
+extern void *tall_pcu_ctx;
 
 /*
  * SYSMO-PCU socket functions
@@ -219,7 +220,7 @@
 
 	state = pcu_sock_state;
 	if (!state) {
-		state = talloc_zero(NULL, struct pcu_sock_state);
+		state = talloc_zero(tall_pcu_ctx, struct pcu_sock_state);
 		if (!state)
 			return -ENOMEM;
 		INIT_LLIST_HEAD(&state->upqueue);