aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2012-12-02 23:55:40 -0500
committerMike Frysinger <vapier@gentoo.org>2012-12-24 00:23:50 -0500
commit9adf0645e69835f1f39c8857939209b6842fa5ee (patch)
tree583ee5f7d2c0654e5e4bf86b69cf87075d8f9f4a
parentsandbox: allow log files to fallback to tmpdir (diff)
downloadsandbox-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>
-rw-r--r--libsbutil/sb_efuncs.c24
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, ...)