diff options
author | Mike Frysinger <vapier@gentoo.org> | 2012-12-02 23:55:40 -0500 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2012-12-24 00:23:50 -0500 |
commit | 9adf0645e69835f1f39c8857939209b6842fa5ee (patch) | |
tree | 583ee5f7d2c0654e5e4bf86b69cf87075d8f9f4a /libsbutil | |
parent | sandbox: allow log files to fallback to tmpdir (diff) | |
download | sandbox-9adf0645e69835f1f39c8857939209b6842fa5ee.tar.gz sandbox-9adf0645e69835f1f39c8857939209b6842fa5ee.tar.bz2 sandbox-9adf0645e69835f1f39c8857939209b6842fa5ee.zip |
sb_efuncs: fix usage of portage handlers
The previous change forgot to actually enable the portage helpers. This
meant violation output would always get sent to /dev/tty rather than to
portage's logging facilities.
Enable the helper logic while also fixing a logic error with va_args
(you can't re-use the same va_args).
Also, in order to use these with code that watches over SIGCHLD via
sigaction, we need to use sigaction ourselves to ignore that signal.
This might be racy with threaded apps that fork & watch SIGCHLD.
Testing in the larger world will show whether we need to revisit
how we communicate with the PM.
URL: http://bugs.gentoo.org/431638
Reported-by: Michael Weiser <michael@weiser.dinsnail.net>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'libsbutil')
-rw-r--r-- | libsbutil/sb_efuncs.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/libsbutil/sb_efuncs.c b/libsbutil/sb_efuncs.c index 6a7a09b..64ac82f 100644 --- a/libsbutil/sb_efuncs.c +++ b/libsbutil/sb_efuncs.c @@ -26,7 +26,7 @@ static void sbio_init(void) } } -static bool try_portage_helpers = false; +static bool try_portage_helpers = true; /* * First try to use the helper programs from portage so that it can sanely @@ -39,17 +39,20 @@ static void sb_vefunc(const char *prog, const char *color, const char *format, v { char shellcode[128]; FILE *fp; - sighandler_t oldsig; + struct sigaction sa, old_sa; bool is_pipe = false; + va_list retry_args; if (try_portage_helpers) { /* If popen() fails, then writes to it will trigger SIGPIPE */ - /* XXX: convert this to sigaction */ - oldsig = signal(SIGPIPE, SIG_IGN); + sa.sa_flags = SA_RESTART; + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, &old_sa); sprintf(shellcode, "xargs %s 2>/dev/null", prog); fp = sbio_popen(shellcode, "we"); is_pipe = true; + va_copy(retry_args, args); } else fp = NULL; @@ -68,13 +71,20 @@ static void sb_vefunc(const char *prog, const char *color, const char *format, v if (is_pipe) { int status = pclose(fp); - if (WEXITSTATUS(status)) + if (WEXITSTATUS(status)) { + args = retry_args; goto do_tty; + } } else if (fp != stderr) fclose(fp); - if (try_portage_helpers) - signal(SIGPIPE, oldsig); + if (try_portage_helpers) { + sigaction(SIGCHLD, &old_sa, NULL); + va_end(retry_args); + if (!is_pipe) + /* If we failed once, we'll fail again */ + try_portage_helpers = false; + } } void sb_einfo(const char *format, ...) |