Index: developers/werner/owping/rx.c
===================================================================
--- developers/werner/owping/rx.c	(revision 4764)
+++ developers/werner/owping/rx.c	(revision 4775)
@@ -15,6 +15,8 @@
 #include <stdlib.h>
 #include <stdio.h>
+#include <unistd.h>
 #include <string.h>
 #include <math.h>
+#include <signal.h>
 #include <sys/time.h>
 #include <sys/socket.h>
@@ -29,5 +31,5 @@
     double sum, sq;
     int n;
-};
+} stats_itf, stats_user;
 
 
@@ -42,9 +44,8 @@
     double avg = stats->sum/stats->n;
 
-    printf("%s min/avg/max/sdev = %.3f/%.3f/%.3f/%.3f ms (%d packets)\n",
+    printf("%s min/avg/max/sdev = %.3f/%.3f/%.3f/%.3f ms\n",
       label,
       stats->min/1000.0, avg/1000.0, stats->max/1000.0,
-      sqrt(stats->sq/stats->n-avg*avg)/1000.0,
-      stats->n);
+      sqrt(stats->sq/stats->n-avg*avg)/1000.0);
 }
 
@@ -78,8 +79,41 @@
 
 
-void rx(int port)
+static void finish(void)
 {
-    struct stats stats_itf, stats_user;
-    struct sockaddr_in addr;
+    printf("received %d packets\n", stats_itf.n);
+    stats_print("itf:", &stats_itf);
+    stats_print("app:", &stats_user);
+}
+
+
+static void handler(int sig)
+{
+    finish();
+    _exit(0);
+}
+
+
+static void block(int how)
+{
+    sigset_t set;
+
+    if (sigemptyset(&set) < 0) {
+	perror("sigemptyset");
+	exit(1);
+    }
+    if (sigaddset(&set, SIGINT) < 0) {
+	perror("sigaddset");
+	exit(1);
+    }
+    if (sigprocmask(how, &set, NULL) < 0) {
+	perror("sigprocmask");
+	exit(1);
+    }
+}
+
+
+void rx(const struct sockaddr_in *addr)
+{
+    struct sockaddr_in src;
     int s;
 
@@ -90,8 +124,5 @@
     }
 
-    addr.sin_family = AF_INET;
-    addr.sin_addr.s_addr = INADDR_ANY;
-    addr.sin_port = htons(port);
-    if (bind(s, (const struct sockaddr *) &addr, sizeof(addr)) < 0) {
+    if (bind(s, (const struct sockaddr *) addr, sizeof(*addr)) < 0) {
 	perror("bind");
 	exit(1);
@@ -101,4 +132,13 @@
     stats_init(&stats_user);
 
+    if (atexit(finish)) {
+	perror("atexit");
+	exit(1);
+    }
+    if (signal(SIGINT, handler) == SIG_ERR) {
+	perror("signal(SIGINT)");
+	exit(1);
+    }
+
     while (1) {
 	struct owping buf;
@@ -107,7 +147,7 @@
 	struct timeval t_src, t_itf, t_user;
 
-	addr_len = sizeof(addr);
+	addr_len = sizeof(src);
 	got = recvfrom(s, &buf, sizeof(buf), 0,
-	  (struct sockaddr *) &addr, &addr_len);
+	  (struct sockaddr *) &src, &addr_len);
 	if (got < 0) {
 	    perror("recvmsg");
@@ -129,6 +169,7 @@
 	    exit(1);
 	}
+	block(SIG_BLOCK);
 	printf("seq=%u from %s:", (unsigned) ntohl(buf.seq),
-	  inet_ntoa(addr.sin_addr));
+	  inet_ntoa(src.sin_addr));
 	t_src.tv_sec = ntohl(buf.tv_sec);
 	t_src.tv_usec = ntohl(buf.tv_usec);
@@ -136,7 +177,5 @@
 	delta(t_src, t_user, &stats_user);
 	putchar('\n');
+	block(SIG_UNBLOCK);
     }
-    stats_print("itf:", &stats_itf);
-    stats_print("app:", &stats_user);
-
 }
