From f3410da7f0bd208a5f2d792131b215454e782e93 Mon Sep 17 00:00:00 2001 From: Jonathan McCrohan Date: Sun, 5 Feb 2012 19:04:33 +0000 Subject: Imported Upstream version 0.7.3 --- error.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 8 deletions(-) (limited to 'error.c') diff --git a/error.c b/error.c index 4c8a1ff..5408c07 100644 --- a/error.c +++ b/error.c @@ -19,6 +19,31 @@ */ #include "wavemon.h" #include +#if HAVE_LIBCAP +#include + +static bool has_capability(cap_value_t cap) +{ + cap_t cap_proc = cap_get_proc(); + cap_flag_value_t cur_val; + + if (cap_get_flag(cap_proc, cap, CAP_EFFECTIVE, &cur_val)) + err_sys("cap_get_flag(CAP_EFFECTIVE)"); + cap_free(cap_proc); + + return cur_val == CAP_SET; +} + +bool has_net_admin_capability(void) +{ + return has_capability(CAP_NET_ADMIN); +} +#else /* !HAVE_LIBCAP */ +bool has_net_admin_capability(void) +{ + return geteuid() == 0; +} +#endif /* * For displaying warning messages that are unrelated to system calls, @@ -34,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. */ @@ -41,11 +94,8 @@ void err_quit(const char *format, ...) { va_list argp; - endwin(); - va_start(argp, format); - verrx(EXIT_FAILURE, format, argp); - va_end(argp); + terminate_all_processes(format, false, argp); } /* @@ -55,9 +105,6 @@ void err_sys(const char *format, ...) { va_list argp; - endwin(); - va_start(argp, format); - verr(EXIT_FAILURE, format, argp); - va_end(argp); + terminate_all_processes(format, true, argp); } -- cgit v1.2.3