summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/forkfd
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-06-06 08:34:03 +0200
committerLiang Qi <liang.qi@qt.io>2016-06-06 09:04:55 +0200
commit57057f76add416d0faf2e09a90c126baafb6198e (patch)
tree07d54f8e5daeb3ed1161723542e94c324d745166 /src/3rdparty/forkfd
parentdc0ae02ebc8e221f952829230c0301a718a6f10b (diff)
parentfd70978693bd92761e9989bc1c76bf83c1e8c987 (diff)
Merge remote-tracking branch 'origin/5.6' into 5.7
Conflicts: .qmake.conf config.tests/unix/nis/nis.cpp mkspecs/unsupported/freebsd-g++/qplatformdefs.h src/corelib/tools/qdatetime.cpp src/corelib/tools/qsimd.cpp src/corelib/tools/qsimd_p.h src/network/access/access.pri src/network/access/qnetworkreplynsurlconnectionimpl.mm src/network/access/qnetworkreplynsurlconnectionimpl_p.h src/plugins/platforms/cocoa/qnsview.mm src/plugins/printsupport/windows/qwindowsprintdevice.cpp tests/auto/corelib/kernel/qobject/tst_qobject.cpp tests/auto/network/access/qnetworkreply/BLACKLIST tests/auto/widgets/widgets/qopenglwidget/BLACKLIST Change-Id: I4b32055bbf922392ef0264fd403405416fffee57
Diffstat (limited to 'src/3rdparty/forkfd')
-rw-r--r--src/3rdparty/forkfd/forkfd.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c
index ad05ab1a01..7b711e197b 100644
--- a/src/3rdparty/forkfd/forkfd.c
+++ b/src/3rdparty/forkfd/forkfd.c
@@ -30,6 +30,9 @@
#include "forkfd.h"
#include <sys/types.h>
+#if defined(__OpenBSD__) || defined(__NetBSD__)
+# include <sys/param.h>
+#endif
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
@@ -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__) || \
@@ -410,6 +415,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 +471,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 +516,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;