From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Sun, 27 Feb 2011 20:41:48 +0000 (+0100)
Subject: Better termination
X-Git-Url: http://eden-feed.erg.abdn.ac.uk/cgi-bin/gitweb.cgi?p=wavemon.git;a=commitdiff_plain;h=633c66a214c68af9a54d123307dc1e1209240472

Better termination

This fixes two flaws in the attempt to terminate the other wavemon processes
on error: (i) it was not ensured that wavemon runs in its own process group;
(ii) sending the signal to self is ugly.
---

diff --git a/error.c b/error.c
index 592d3e4..5408c07 100644
--- a/error.c
+++ b/error.c
@@ -59,6 +59,34 @@ void err_msg(const char *format, ...)
 	sleep(WARN_DISPLAY_DELAY);
 }
 
+/**
+ * terminate_all_processes  -  terminate wavemon and reset screen
+ * @fmt:     printf-like format string
+ * @strerr:  set to non-0 if termination is due to failed system call
+ * @ap:	     argument list for @fmt
+ */
+static void terminate_all_processes(const char *fmt, int strerr, va_list ap)
+{
+	int saved_errno = strerr ? errno : 0;
+	/*
+	 * wavemon runs in its own process group. Block TERM in this process,
+	 * but send to all others (parent or child), which by default do not
+	 * block TERM.
+	 */
+	xsignal(SIGTERM, SIG_IGN);
+	endwin();
+	kill(0, SIGTERM);
+	reset_shell_mode();
+	if (saved_errno) {
+		errno = saved_errno;
+		vwarn(fmt, ap);
+	} else {
+		vwarnx(fmt, ap);
+	}
+	va_end(ap);
+	exit(EXIT_FAILURE);
+}
+
 /*
  * Abort on fatal error unrelated to system call.
  */
@@ -66,13 +94,8 @@ void err_quit(const char *format, ...)
 {
 	va_list argp;
 
-	endwin();
-
 	va_start(argp, format);
-	vwarnx(format, argp);
-	va_end(argp);
-	/* Exit via kill to terminate any child processes. */
-	kill(0, SIGTERM);
+	terminate_all_processes(format, false, argp);
 }
 
 /*
@@ -82,10 +105,6 @@ void err_sys(const char *format, ...)
 {
 	va_list argp;
 
-	endwin();
-
 	va_start(argp, format);
-	vwarn(format, argp);
-	va_end(argp);
-	kill(0, SIGTERM);
+	terminate_all_processes(format, true, argp);
 }
diff --git a/wavemon.c b/wavemon.c
index 6c3196e..4e1f492 100644
--- a/wavemon.c
+++ b/wavemon.c
@@ -139,6 +139,7 @@ int main(int argc, char *argv[])
 
 	if (!isatty(STDIN_FILENO))
 		errx(1, "input is not from a terminal");
+	setpgid(0, 0);
 
 	/* honour numeric separators if the environment defines them */
 	setlocale(LC_NUMERIC, "");