summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/forkfd
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2016-05-22 11:18:34 -0700
committerThiago Macieira <thiago.macieira@intel.com>2016-05-23 18:22:07 +0000
commitcf6a2e96175b7ec2be757ae247ffd86e28ac563b (patch)
treeb09fbf3827c136c8ade7160cf21861cc0f444572 /src/3rdparty/forkfd
parent3cae115d6d6e8a1d4d0385e3cde16f59b25acad0 (diff)
forkfd: Make sure we handle SIGPIPE too
We can't depend on the application/library ignoring the signal for us, so we do it. O_NOSIGPIPE exists on the BSDs and I'll add it to Linux. If it isn't supported, then we need to ignore SIGPIPE globally. Change-Id: I25d85d86649448d5b2b3fffd1450f6afeaea8b18 Reviewed-by: Ralf Nolden <nolden@kde.org> Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com>
Diffstat (limited to 'src/3rdparty/forkfd')
-rw-r--r--src/3rdparty/forkfd/forkfd.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c
index fef710a79e..9284a67674 100644
--- a/src/3rdparty/forkfd/forkfd.c
+++ b/src/3rdparty/forkfd/forkfd.c
@@ -410,6 +410,26 @@ chain_handler:
old_sigaction.sa_handler(signum);
}
+static void ignore_sigpipe()
+{
+#ifdef O_NOSIGPIPE
+ static ffd_atomic_int done = FFD_ATOMIC_INIT(0);
+ if (ffd_atomic_load(&done, FFD_ATOMIC_RELAXED))
+ return;
+#endif
+
+ struct sigaction action;
+ memset(&action, 0, sizeof action);
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ action.sa_flags = 0;
+ sigaction(SIGPIPE, &action, NULL);
+
+#ifdef O_NOSIGPIPE
+ ffd_atomic_store(&done, 1, FFD_ATOMIC_RELAXED);
+#endif
+}
+
static void forkfd_initialize()
{
#if defined(HAVE_BROKEN_WAITID)
@@ -446,6 +466,11 @@ static void forkfd_initialize()
*/
sigaction(SIGCHLD, &action, &old_sigaction);
+#ifndef O_NOSIGPIPE
+ /* disable SIGPIPE too */
+ ignore_sigpipe();
+#endif
+
#ifndef __GNUC__
atexit(cleanup);
#endif
@@ -486,13 +511,23 @@ static void cleanup()
static int create_pipe(int filedes[], int flags)
{
- int ret;
+ int ret = -1;
#ifdef HAVE_PIPE2
/* use pipe2(2) whenever possible, since it can thread-safely create a
* cloexec pair of pipes. Without it, we have a race condition setting
* FD_CLOEXEC
*/
- ret = pipe2(filedes, O_CLOEXEC);
+
+# ifdef O_NOSIGPIPE
+ /* try first with O_NOSIGPIPE */
+ ret = pipe2(filedes, O_CLOEXEC | O_NOSIGPIPE);
+ if (ret == -1) {
+ /* O_NOSIGPIPE not supported, ignore SIGPIPE */
+ ignore_sigpipe();
+ }
+# endif
+ if (ret == -1)
+ ret = pipe2(filedes, O_CLOEXEC);
if (ret == -1)
return ret;