summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qcore_unix.cpp20
-rw-r--r--src/corelib/kernel/qcore_unix_p.h8
2 files changed, 28 insertions, 0 deletions
diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp
index eb98cbef8f..18c031f137 100644
--- a/src/corelib/kernel/qcore_unix.cpp
+++ b/src/corelib/kernel/qcore_unix.cpp
@@ -44,6 +44,12 @@
#include <stdlib.h>
+#ifdef __GLIBC__
+# include <sys/syscall.h>
+# include <pthread.h>
+# include <unistd.h>
+#endif
+
#ifdef Q_OS_MAC
#include <mach/mach_time.h>
#endif
@@ -79,6 +85,20 @@ QByteArray qt_readlink(const char *path)
return buf;
}
+#if defined(Q_PROCESSOR_X86_32) && defined(__GLIBC__)
+# if !__GLIBC_PREREQ(2, 22)
+// glibc prior to release 2.22 had a bug that suppresses the third argument to
+// open() / open64() / openat(), causing file creation with O_TMPFILE to have
+// the wrong permissions. So we bypass the glibc implementation and go straight
+// for the syscall. See
+// https://sourceware.org/git/?p=glibc.git;a=commit;h=65f6f938cd562a614a68e15d0581a34b177ec29d
+int qt_open64(const char *pathname, int flags, mode_t mode)
+{
+ return syscall(SYS_open, pathname, flags | O_LARGEFILE, mode);
+}
+# endif
+#endif
+
#ifndef QT_BOOTSTRAPPED
#if QT_CONFIG(poll_pollts)
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index e538a7e22b..cb98bef347 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -176,6 +176,14 @@ inline void qt_ignore_sigpipe()
}
}
+#if defined(Q_PROCESSOR_X86_32) && defined(__GLIBC__)
+# if !__GLIBC_PREREQ(2, 22)
+int qt_open64(const char *pathname, int flags, mode_t);
+# undef QT_OPEN
+# define QT_OPEN qt_open64
+# endif
+#endif
+
// don't call QT_OPEN or ::open
// call qt_safe_open
static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 0777)