From: Gerrit Renker 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, "");