summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-03-15 01:00:11 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-03-15 01:00:11 +0100
commit8264e495fa9220c101a8a913701a0b8834a6d58b (patch)
tree069aa1d3efab926991c1edfc5b69a3d9e58dcfba /src/corelib/io
parent80f52812f2651e6d427bb3dd2e338b60fb25d48b (diff)
parent8eb3944dac81b8c51d7bac7784204d457551b50c (diff)
Merge remote-tracking branch 'origin/5.11' into dev
Diffstat (limited to 'src/corelib/io')
-rw-r--r--src/corelib/io/qdir.cpp36
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp23
2 files changed, 51 insertions, 8 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index d043b3aea5..06eacf5455 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -750,13 +750,47 @@ QString QDir::filePath(const QString &fileName) const
QString QDir::absoluteFilePath(const QString &fileName) const
{
const QDirPrivate* d = d_ptr.constData();
- if (isAbsolutePath(fileName))
+ // Don't trust our own isAbsolutePath(); Q_OS_WIN needs a drive.
+ if (QFileSystemEntry(fileName).isAbsolute())
return fileName;
d->resolveAbsoluteEntry();
const QString absoluteDirPath = d->absoluteDirEntry.filePath();
if (fileName.isEmpty())
return absoluteDirPath;
+#ifdef Q_OS_WIN
+ // Handle the "absolute except for drive" case (i.e. \blah not c:\blah):
+ int size = absoluteDirPath.length();
+ if ((fileName.startsWith(QLatin1Char('/'))
+ || fileName.startsWith(QLatin1Char('\\')))
+ && size > 1) {
+ // Combine absoluteDirPath's drive with fileName
+ int drive = 2; // length of drive prefix
+ if (Q_UNLIKELY(absoluteDirPath.at(1).unicode() != ':')) {
+ // Presumably, absoluteDirPath is an UNC path; use its //server/share
+ // part as "drive" - it's as sane a thing as we can do.
+ for (int i = 2; i-- > 0; ) { // Scan two "path fragments":
+ while (drive < size && absoluteDirPath.at(drive).unicode() == '/')
+ drive++;
+ if (drive >= size) {
+ qWarning("Base directory starts with neither a drive nor a UNC share: %s",
+ qPrintable(QDir::toNativeSeparators(absoluteDirPath)));
+ return QString();
+ }
+ while (drive < size && absoluteDirPath.at(drive).unicode() != '/')
+ drive++;
+ }
+ // We'll append fileName, which starts with a slash; so omit trailing slash:
+ if (absoluteDirPath.at(drive).unicode() == '/')
+ drive--;
+ } else if (!absoluteDirPath.at(0).isLetter()) {
+ qWarning("Base directory's drive is not a letter: %s",
+ qPrintable(QDir::toNativeSeparators(absoluteDirPath)));
+ return QString();
+ }
+ return absoluteDirPath.leftRef(drive) % fileName;
+ }
+#endif // Q_OS_WIN
if (!absoluteDirPath.endsWith(QLatin1Char('/')))
return absoluteDirPath % QLatin1Char('/') % fileName;
return absoluteDirPath % fileName;
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index 2a42ad42f9..5cc3a5937e 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -91,26 +91,35 @@ extern "C" NSString *NSTemporaryDirectory();
# include <sys/syscall.h>
# include <sys/sendfile.h>
# include <linux/fs.h>
+# include <linux/stat.h>
// in case linux/fs.h is too old and doesn't define it:
#ifndef FICLONE
# define FICLONE _IOW(0x94, 9, int)
#endif
-# if !QT_CONFIG(renameat2) && defined(SYS_renameat2)
+# if defined(Q_OS_ANDROID)
+// renameat2() and statx() are disabled on Android because quite a few systems
+// come with sandboxes that kill applications that make system calls outside a
+// whitelist and several Android vendors can't be bothered to update the list.
+# undef SYS_renameat2
+# undef SYS_statx
+# undef STATX_BASIC_STATS
+# else
+# if !QT_CONFIG(renameat2) && defined(SYS_renameat2)
static int renameat2(int oldfd, const char *oldpath, int newfd, const char *newpath, unsigned flags)
{ return syscall(SYS_renameat2, oldfd, oldpath, newfd, newpath, flags); }
-# endif
+# endif
-# if !QT_CONFIG(statx) && defined(SYS_statx) && QT_HAS_INCLUDE(<linux/stat.h>)
-# include <linux/stat.h>
+# if !QT_CONFIG(statx) && defined(SYS_statx)
static int statx(int dirfd, const char *pathname, int flag, unsigned mask, struct statx *statxbuf)
{ return syscall(SYS_statx, dirfd, pathname, flag, mask, statxbuf); }
-# endif
+# endif
+# endif // !Q_OS_ANDROID
#endif
-#ifndef STATX_BASIC_STATS
-struct statx { mode_t stx_mode; };
+#ifndef STATX_ALL
+struct statx { mode_t stx_mode; }; // dummy
#endif
QT_BEGIN_NAMESPACE