From 900eb656849d4fa3ff119305c08b631c76fae75e Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Mon, 30 Aug 2010 17:28:02 +0200 Subject: Move canonicalPath() to the new qfilesystemengine_unix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: João Abecasis --- qmake/Makefile.unix | 6 +- qmake/Makefile.win32 | 5 ++ qmake/Makefile.win32-g++ | 4 + qmake/qmake.pri | 1 + src/corelib/io/io.pri | 3 +- src/corelib/io/qfilesystemengine.cpp | 113 +++++++++++++++++++++++++++ src/corelib/io/qfilesystemengine_p.h | 2 + src/corelib/io/qfilesystemengine_unix.cpp | 21 ++++- src/corelib/io/qfsfileengine.cpp | 57 +------------- src/corelib/io/qfsfileengine_unix.cpp | 19 ++--- src/tools/bootstrap/bootstrap.pro | 1 + tools/configure/configure.pro | 1 + tools/qtestlib/wince/cetest/bootstrapped.pri | 1 + 13 files changed, 162 insertions(+), 72 deletions(-) create mode 100644 src/corelib/io/qfilesystemengine.cpp diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index 8c1ac6d..4eba3f5 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -16,7 +16,7 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \ #qt code QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \ qbytearray.o qbytearraymatcher.o qdatastream.o qbuffer.o qlist.o qfile.o \ - qfilesystementry.o qfilesystemengine_unix.o \ + qfilesystementry.o qfilesystemengine_unix.o qfilesystemengine.o \ qfsfileengine_unix.o qfsfileengine_iterator_unix.o qfsfileengine.o \ qfsfileengine_iterator.o qregexp.o qvector.o qbitarray.o qdir.o qdiriterator.o quuid.o qhash.o \ qfileinfo.o qdatetime.o qstringlist.o qabstractfileengine.o qtemporaryfile.o \ @@ -46,6 +46,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp $(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp \ $(SOURCE_PATH)/src/corelib/io/qdatastream.cpp $(SOURCE_PATH)/src/corelib/io/qbuffer.cpp \ $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp \ + $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp \ $(SOURCE_PATH)/src/corelib/io/qfsfileengine_unix.cpp $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp \ $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator_unix.cpp $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator.cpp \ $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp $(SOURCE_PATH)/src/corelib/tools/qlist.cpp \ @@ -165,6 +166,9 @@ qfile.o: $(SOURCE_PATH)/src/corelib/io/qfile.cpp qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp +qfilesystemengine.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp + qfilesystemengine_unix.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index b76348b..ec64fa9 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -89,6 +89,7 @@ QTOBJS= \ qbuffer.obj \ qcryptographichash.obj \ qfilesystementry.obj \ + qfilesystemengine.obj \ qfilesystemengine_win.obj \ qfsfileengine.obj \ qfsfileengine_iterator.obj \ @@ -144,6 +145,7 @@ clean:: -del qcryptographichash.obj -del qlinkedlist.obj -del qfilesystementry.obj + -del qfilesystemengine.obj -del qfilesystemengine_win.obj -del qfsfileengine.obj -del qfsfileengine_iterator.obj @@ -317,6 +319,9 @@ qtemporaryfile.obj: $(SOURCE_PATH)\src\corelib\io\qtemporaryfile.cpp qfilesystementry.obj: $(SOURCE_PATH)\src\corelib\io\qfilesystementry.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\corelib\io\qfilesystementry.cpp +qfilesystemengine.obj: $(SOURCE_PATH)\src\corelib\io\qfilesystemengine.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\corelib\io\qfilesystemengine.cpp + qfilesystemengine_win.obj: $(SOURCE_PATH)\src\corelib\io\qfilesystemengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\corelib\io\qfilesystemengine_win.cpp diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++ index c692731..f2f8386 100644 --- a/qmake/Makefile.win32-g++ +++ b/qmake/Makefile.win32-g++ @@ -62,6 +62,7 @@ QTOBJS= \ qfileinfo.o \ qabstractfileengine.o \ qfilesystementry.o \ + qfilesystemengine.o \ qfilesystemengine_win.o \ qfsfileengine.o \ qfsfileengine_iterator.o \ @@ -197,6 +198,9 @@ qabstractfileengine.o: $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp +qfilesystemengine.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp + qfilesystemengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp diff --git a/qmake/qmake.pri b/qmake/qmake.pri index 4d78c8b..be6a909 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -58,6 +58,7 @@ bootstrap { #Qt code qabstractfileengine.cpp \ qfileinfo.cpp \ qfilesystementry.cpp \ + qfilesystemengine.cpp \ qfsfileengine.cpp \ qfsfileengine_iterator.cpp \ qglobal.cpp \ diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 3bde2de..7a34275 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -56,7 +56,8 @@ SOURCES += \ io/qfsfileengine.cpp \ io/qfsfileengine_iterator.cpp \ io/qfilesystemwatcher.cpp \ - io/qfilesystementry.cpp + io/qfilesystementry.cpp \ + io/qfilesystemengine.cpp win32 { SOURCES += io/qsettings_win.cpp diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp new file mode 100644 index 0000000..04e53ce --- /dev/null +++ b/src/corelib/io/qfilesystemengine.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qfilesystemengine_p.h" +#include +#include + +/*! + \internal + + Returns the canonicalized form of \a path (i.e., with all symlinks + resolved, and all redundant path elements removed. +*/ +QString QFileSystemEngine::slowCanonicalized(const QString &path) +{ + if (path.isEmpty()) + return path; + + QFileInfo fi; + const QChar slash(QLatin1Char('/')); + QString tmpPath = path; + int separatorPos = 0; + QSet nonSymlinks; + QSet known; + + known.insert(path); + do { +#ifdef Q_OS_WIN + if (separatorPos == 0) { + if (tmpPath.size() >= 2 && tmpPath.at(0) == slash && tmpPath.at(1) == slash) { + // UNC, skip past the first two elements + separatorPos = tmpPath.indexOf(slash, 2); + } else if (tmpPath.size() >= 3 && tmpPath.at(1) == QLatin1Char(':') && tmpPath.at(2) == slash) { + // volume root, skip since it can not be a symlink + separatorPos = 2; + } + } + if (separatorPos != -1) +#endif + separatorPos = tmpPath.indexOf(slash, separatorPos + 1); + QString prefix = separatorPos == -1 ? tmpPath : tmpPath.left(separatorPos); + if ( +#ifdef Q_OS_SYMBIAN + // Symbian doesn't support directory symlinks, so do not check for link unless we + // are handling the last path element. This not only slightly improves performance, + // but also saves us from lot of unnecessary platform security check failures + // when dealing with files under *:/private directories. + separatorPos == -1 && +#endif + !nonSymlinks.contains(prefix)) { + fi.setFile(prefix); + if (fi.isSymLink()) { + QString target = fi.symLinkTarget(); + if(QFileInfo(target).isRelative()) + target = fi.absolutePath() + slash + target; + if (separatorPos != -1) { + if (fi.isDir() && !target.endsWith(slash)) + target.append(slash); + target.append(tmpPath.mid(separatorPos)); + } + tmpPath = QDir::cleanPath(target); + separatorPos = 0; + + if (known.contains(tmpPath)) + return QString(); + known.insert(tmpPath); + } else { + nonSymlinks.insert(prefix); + } + } + } while (separatorPos != -1); + + return QDir::cleanPath(tmpPath); +} + diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index c1bb3b4..61ca085 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -84,6 +84,8 @@ public: static bool setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QFileSystemMetaData *data = 0); + + static QString slowCanonicalized(const QString &path); }; QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 68cc154..283c787 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -42,6 +42,9 @@ #include "qfilesystemengine_p.h" #include "qfsfileengine.h" +#include // for realpath() +#include + QT_BEGIN_NAMESPACE bool QFileSystemEngine::isCaseSensitive() @@ -62,7 +65,23 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link) //static QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) { - return entry; // TODO implement; + if (entry.isEmpty() || entry.isRoot()) + return entry; + +#ifdef __UCLIBC__ + return QFileSystemEntry::slowCanonicalName(entry); +#else + + char *ret = realpath(entry.nativeFilePath().constData(), (char*)0); + if (ret) { + QString canonicalPath = QDir::cleanPath(QString::fromLocal8Bit(ret)); + free(ret); + return QFileSystemEntry(canonicalPath); + } else if (errno == ENOENT) { // file doesn't exist + return QFileSystemEntry(); + } + return entry; +#endif } //static diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 75f82a6..665d23e 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -41,6 +41,7 @@ #include "qfsfileengine_p.h" #include "qfsfileengine_iterator_p.h" +#include "qfilesystemengine_p.h" #include "qdatetime.h" #include "qdiriterator.h" #include "qset.h" @@ -179,61 +180,7 @@ QString QFSFileEnginePrivate::canonicalized(const QString &path) #endif #endif - QFileInfo fi; - const QChar slash(QLatin1Char('/')); - QString tmpPath = path; - int separatorPos = 0; - QSet nonSymlinks; - QSet known; - - known.insert(path); - do { -#ifdef Q_OS_WIN - if (separatorPos == 0) { - if (tmpPath.size() >= 2 && tmpPath.at(0) == slash && tmpPath.at(1) == slash) { - // UNC, skip past the first two elements - separatorPos = tmpPath.indexOf(slash, 2); - } else if (tmpPath.size() >= 3 && tmpPath.at(1) == QLatin1Char(':') && tmpPath.at(2) == slash) { - // volume root, skip since it can not be a symlink - separatorPos = 2; - } - } - if (separatorPos != -1) -#endif - separatorPos = tmpPath.indexOf(slash, separatorPos + 1); - QString prefix = separatorPos == -1 ? tmpPath : tmpPath.left(separatorPos); - if ( -#ifdef Q_OS_SYMBIAN - // Symbian doesn't support directory symlinks, so do not check for link unless we - // are handling the last path element. This not only slightly improves performance, - // but also saves us from lot of unnecessary platform security check failures - // when dealing with files under *:/private directories. - separatorPos == -1 && -#endif - !nonSymlinks.contains(prefix)) { - fi.setFile(prefix); - if (fi.isSymLink()) { - QString target = fi.symLinkTarget(); - if(QFileInfo(target).isRelative()) - target = fi.absolutePath() + slash + target; - if (separatorPos != -1) { - if (fi.isDir() && !target.endsWith(slash)) - target.append(slash); - target.append(tmpPath.mid(separatorPos)); - } - tmpPath = QDir::cleanPath(target); - separatorPos = 0; - - if (known.contains(tmpPath)) - return QString(); - known.insert(tmpPath); - } else { - nonSymlinks.insert(prefix); - } - } - } while (separatorPos != -1); - - return QDir::cleanPath(tmpPath); + return QFileSystemEngine::slowCanonicalized(path); } /*! diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 3daf7f6..29491f5 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -1027,25 +1027,16 @@ QString QFSFileEngine::fileName(FileName file) const } else if (file == PathName) { return d->fileEntry.path(); } else if (file == AbsoluteName || file == AbsolutePathName) { - QFileSystemEntry entry = QFileSystemEngine::absoluteName(d->fileEntry); + QFileSystemEntry entry(QFileSystemEngine::absoluteName(d->fileEntry)); if (file == AbsolutePathName) { return entry.path(); } return entry.filePath(); } else if (file == CanonicalName || file == CanonicalPathName) { - if (!(fileFlags(ExistsFlag) & ExistsFlag)) - return QString(); - - QString ret = QFSFileEnginePrivate::canonicalized(fileName(AbsoluteName)); - if (file == CanonicalPathName && !ret.isEmpty()) { - int slash = ret.lastIndexOf(QLatin1Char('/')); - if (slash == -1) - ret = QDir::currentPath(); - else if (slash == 0) - ret = QLatin1String("/"); - ret = ret.left(slash); - } - return ret; + QFileSystemEntry entry(QFileSystemEngine::canonicalName(d->fileEntry)); + if (file == CanonicalPathName) + return entry.path(); + return entry.filePath(); } else if (file == LinkName) { if (d->isSymlink()) { #if defined(__GLIBC__) && !defined(PATH_MAX) diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index bec1329..9adba9c 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -58,6 +58,7 @@ SOURCES += \ ../../corelib/io/qfile.cpp \ ../../corelib/io/qfileinfo.cpp \ ../../corelib/io/qfilesystementry.cpp \ + ../../corelib/io/qfilesystemengine.cpp \ ../../corelib/io/qfsfileengine.cpp \ ../../corelib/io/qfsfileengine_iterator.cpp \ ../../corelib/io/qiodevice.cpp \ diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index 9e52f81..854a0e4 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -90,6 +90,7 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfileinfo.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qabstractfileengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfilesystementry.cpp \ + $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine_win.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_win.cpp \ diff --git a/tools/qtestlib/wince/cetest/bootstrapped.pri b/tools/qtestlib/wince/cetest/bootstrapped.pri index 0af5c94..f33dde8 100644 --- a/tools/qtestlib/wince/cetest/bootstrapped.pri +++ b/tools/qtestlib/wince/cetest/bootstrapped.pri @@ -5,6 +5,7 @@ SOURCES += \ $$QT_SOURCE_TREE/src/corelib/io/qfile.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qdir.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfilesystementry.cpp \ + $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine_win.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qabstractfileengine.cpp \ -- cgit v0.12