From cf6a2e96175b7ec2be757ae247ffd86e28ac563b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 22 May 2016 11:18:34 -0700 Subject: 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 Reviewed-by: Rafael Roquetto --- src/3rdparty/forkfd/forkfd.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'src/3rdparty') 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; -- cgit v1.2.3 From 4fc797147821b4ef3372d4db9253d3cb1ed0704e Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Thu, 2 Jun 2016 13:46:52 +0200 Subject: NetBSD/OpenBSD: Compile fix and proper detection of pipe2 Add the necessary defines for HAVE_PIPE2 for NetBSD and OpenBSD depending on OS version when pipe2(2) was added. This also fixes the compile error on NetBSD if -Werror=unused-function for ignore_sigpipe() as the HAVE_PIPE2 tree is prior to O_NOSIGPIPE in create_pipe(). Change-Id: Ic8f875e34ef826a7bf046c77588afecaa097deca Reviewed-by: Thiago Macieira --- src/3rdparty/forkfd/forkfd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/3rdparty') diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c index 9284a67674..7d2115abb6 100644 --- a/src/3rdparty/forkfd/forkfd.c +++ b/src/3rdparty/forkfd/forkfd.c @@ -30,6 +30,9 @@ #include "forkfd.h" #include +#if defined(__OpenBSD__) || defined(__NetBSD__) +# include +#endif #include #include #include @@ -65,7 +68,9 @@ # undef HAVE_WAITID #endif -#if defined(__FreeBSD__) && defined(__FreeBSD_version) && __FreeBSD_version >= 1000032 +#if (defined(__FreeBSD__) && defined(__FreeBSD_version) && __FreeBSD_version >= 1000032) || \ + (defined(__OpenBSD__) && OpenBSD >= 201505) || \ + (defined(__NetBSD__) && __NetBSD_Version__ >= 600000000) # define HAVE_PIPE2 1 #endif #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) || \ -- cgit v1.2.3