diff options
-rw-r--r-- | src/corelib/io/io.pri | 1 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_p.h | 2 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_unix.cpp | 161 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemmetadata_p.h | 4 | ||||
-rw-r--r-- | src/corelib/io/qstorageinfo_mac.cpp | 40 |
6 files changed, 94 insertions, 116 deletions
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index f496d037d8..b2bcbdf727 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -160,6 +160,7 @@ win32 { } else:ios { OBJECTIVE_SOURCES += io/qstandardpaths_ios.mm SOURCES += io/qstorageinfo_mac.cpp + LIBS += -framework MobileCoreServices } else { SOURCES += io/qstandardpaths_unix.cpp } diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index df41457a18..e4dec2b7fb 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -264,7 +264,7 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) // Attributes entryFlags |= QFileSystemMetaData::ExistsAttribute; size_ = statBuffer.st_size; -#if defined(Q_OS_MACX) +#if defined(Q_OS_DARWIN) if (statBuffer.st_flags & UF_HIDDEN) { entryFlags |= QFileSystemMetaData::HiddenAttribute; knownFlagsMask |= QFileSystemMetaData::HiddenAttribute; diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index 06d5db637a..6db9319836 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -76,7 +76,7 @@ public: static QString resolveGroupName(uint groupId); #endif -#if defined(Q_OS_MACX) +#if defined(Q_OS_DARWIN) static QString bundleName(const QFileSystemEntry &entry); #else static QString bundleName(const QFileSystemEntry &entry) { Q_UNUSED(entry) return QString(); } diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 2c9fed530b..7bc2293b0d 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -51,26 +51,38 @@ # include <CoreFoundation/CFBundle.h> #endif +#ifdef Q_OS_OSX +#include <CoreServices/CoreServices.h> +#endif + +#ifdef Q_OS_IOS +#include <MobileCoreServices/MobileCoreServices.h> +#endif + QT_BEGIN_NAMESPACE -#if defined(Q_OS_MACX) -static inline bool _q_isMacHidden(const char *nativePath) +#if defined(Q_OS_DARWIN) +static inline bool hasResourcePropertyFlag(const QFileSystemMetaData &data, + const QFileSystemEntry &entry, + CFStringRef key) { - OSErr err; - - FSRef fsRef; - err = FSPathMakeRefWithOptions(reinterpret_cast<const UInt8 *>(nativePath), - kFSPathMakeRefDoNotFollowLeafSymlink, &fsRef, 0); - if (err != noErr) + QCFString path = CFStringCreateWithFileSystemRepresentation(0, + entry.nativeFilePath().constData()); + if (!path) return false; - FSCatalogInfo catInfo; - err = FSGetCatalogInfo(&fsRef, kFSCatInfoFinderInfo, &catInfo, NULL, NULL, NULL); - if (err != noErr) + QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, path, kCFURLPOSIXPathStyle, + data.hasFlags(QFileSystemMetaData::DirectoryType)); + if (!url) return false; - FileInfo * const fileInfo = reinterpret_cast<FileInfo*>(&catInfo.finderInfo); - return (fileInfo->finderFlags & kIsInvisible); + CFBooleanRef value; + if (CFURLCopyResourcePropertyForKey(url, key, &value, NULL)) { + if (value == kCFBooleanTrue) + return true; + } + + return false; } static bool isPackage(const QFileSystemMetaData &data, const QFileSystemEntry &entry) @@ -97,6 +109,7 @@ static bool isPackage(const QFileSystemMetaData &data, const QFileSystemEntry &e if (CFBundleGetPackageInfoInDirectory(url, &type, &creator)) return true; +#ifdef Q_OS_OSX // Find if an application other than Finder claims to know how to handle the package QCFType<CFURLRef> application; LSGetApplicationForURL(url, @@ -111,30 +124,11 @@ static bool isPackage(const QFileSystemMetaData &data, const QFileSystemEntry &e if (applicationId != QLatin1String("com.apple.finder")) return true; } +#endif } // Third step: check if the directory has the package bit set - FSRef packageRef; - FSPathMakeRef((UInt8 *)entry.nativeFilePath().constData(), &packageRef, NULL); - - FSCatalogInfo catalogInfo; - FSGetCatalogInfo(&packageRef, - kFSCatInfoFinderInfo, - &catalogInfo, - NULL, - NULL, - NULL); - - FolderInfo *folderInfo = reinterpret_cast<FolderInfo *>(catalogInfo.finderInfo); - return folderInfo->finderFlags & kHasBundle; -} - -#else -static inline bool _q_isMacHidden(const char *nativePath) -{ - Q_UNUSED(nativePath); - // no-op - return false; + return hasResourcePropertyFlag(data, entry, kCFURLIsPackageKey); } #endif @@ -194,21 +188,34 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, ret.chop(1); return QFileSystemEntry(ret); } -#if defined(Q_OS_MACX) +#if defined(Q_OS_DARWIN) { - FSRef fref; - if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(link.filePath())).data(), &fref, 0) == noErr) { - // TODO get the meta data info from the QFileSystemMetaData object - Boolean isAlias, isFolder; - if (FSResolveAliasFile(&fref, true, &isFolder, &isAlias) == noErr && isAlias) { - AliasHandle alias; - if (FSNewAlias(0, &fref, &alias) == noErr && alias) { - QCFString cfstr; - if (FSCopyAliasInfo(alias, 0, 0, &cfstr, 0, 0) == noErr) - return QFileSystemEntry(QCFString::toQString(cfstr)); - } - } - } + QCFString path = CFStringCreateWithFileSystemRepresentation(0, + QFile::encodeName(QDir::cleanPath(link.filePath())).data()); + if (!path) + return QFileSystemEntry(); + + QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, path, kCFURLPOSIXPathStyle, + data.hasFlags(QFileSystemMetaData::DirectoryType)); + if (!url) + return QFileSystemEntry(); + + QCFType<CFDataRef> bookmarkData = CFURLCreateBookmarkDataFromFile(0, url, NULL); + if (!bookmarkData) + return QFileSystemEntry(); + + QCFType<CFURLRef> resolvedUrl = CFURLCreateByResolvingBookmarkData(0, + bookmarkData, + (CFURLBookmarkResolutionOptions)(kCFBookmarkResolutionWithoutUIMask + | kCFBookmarkResolutionWithoutMountingMask), NULL, NULL, NULL, NULL); + if (!resolvedUrl) + return QFileSystemEntry(); + + QCFString cfstr(CFURLCopyFileSystemPath(resolvedUrl, kCFURLPOSIXPathStyle)); + if (!cfstr) + return QFileSystemEntry(); + + return QFileSystemEntry(QCFString::toQString(cfstr)); } #endif return QFileSystemEntry(); @@ -226,31 +233,14 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath())); #else char *ret = 0; -# if defined(Q_OS_MACX) - // When using -mmacosx-version-min=10.4, we get the legacy realpath implementation, - // which does not work properly with the realpath(X,0) form. See QTBUG-28282. - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) { - ret = (char*)malloc(PATH_MAX + 1); - if (ret && realpath(entry.nativeFilePath().constData(), (char*)ret) == 0) { - const int savedErrno = errno; // errno is checked below, and free() might change it - free(ret); - errno = savedErrno; - ret = 0; - } - } else { - // on 10.5 we can use FSRef to resolve the file path. - QString path = QDir::cleanPath(entry.filePath()); - FSRef fsref; - if (FSPathMakeRef((const UInt8 *)path.toUtf8().data(), &fsref, 0) == noErr) { - CFURLRef urlref = CFURLCreateFromFSRef(NULL, &fsref); - CFStringRef canonicalPath = CFURLCopyFileSystemPath(urlref, kCFURLPOSIXPathStyle); - QString ret = QCFString::toQString(canonicalPath); - CFRelease(canonicalPath); - CFRelease(urlref); - return QFileSystemEntry(ret); - } +# if defined(Q_OS_DARWIN) + ret = (char*)malloc(PATH_MAX + 1); + if (ret && realpath(entry.nativeFilePath().constData(), (char*)ret) == 0) { + const int savedErrno = errno; // errno is checked below, and free() might change it + free(ret); + errno = savedErrno; + ret = 0; } - # elif defined(Q_OS_ANDROID) // On some Android versions, realpath() will return a path even if it does not exist // To work around this, we check existence in advance. @@ -406,7 +396,7 @@ QString QFileSystemEngine::resolveGroupName(uint groupId) return QString(); } -#if defined(Q_OS_MACX) +#if defined(Q_OS_DARWIN) //static QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) { @@ -426,7 +416,7 @@ QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) { -#if defined(Q_OS_MACX) +#if defined(Q_OS_DARWIN) if (what & QFileSystemMetaData::BundleType) { if (!data.hasFlags(QFileSystemMetaData::DirectoryType)) what |= QFileSystemMetaData::DirectoryType; @@ -435,7 +425,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM // OS X >= 10.5: st_flags & UF_HIDDEN what |= QFileSystemMetaData::PosixStatFlags; } -#endif // defined(Q_OS_MACX) +#endif // defined(Q_OS_DARWIN) if (what & QFileSystemMetaData::PosixStatFlags) what |= QFileSystemMetaData::PosixStatFlags; @@ -496,19 +486,11 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM | QFileSystemMetaData::ExistsAttribute; } -#if defined(Q_OS_MACX) +#if defined(Q_OS_DARWIN) if (what & QFileSystemMetaData::AliasType) { - if (entryExists) { - FSRef fref; - if (FSPathMakeRef((const UInt8 *)nativeFilePath, &fref, NULL) == noErr) { - Boolean isAlias, isFolder; - if (FSIsAliasFile(&fref, &isAlias, &isFolder) == noErr) { - if (isAlias) - data.entryFlags |= QFileSystemMetaData::AliasType; - } - } - } + if (entryExists && hasResourcePropertyFlag(data, entry, kCFURLIsAliasFileKey)) + data.entryFlags |= QFileSystemMetaData::AliasType; data.knownFlagsMask |= QFileSystemMetaData::AliasType; } #endif @@ -537,12 +519,15 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM && !data.isHidden()) { QString fileName = entry.fileName(); if ((fileName.size() > 0 && fileName.at(0) == QLatin1Char('.')) - || (entryExists && _q_isMacHidden(nativeFilePath))) +#if defined(Q_OS_DARWIN) + || (entryExists && hasResourcePropertyFlag(data, entry, kCFURLIsHiddenKey)) +#endif + ) data.entryFlags |= QFileSystemMetaData::HiddenAttribute; data.knownFlagsMask |= QFileSystemMetaData::HiddenAttribute; } -#if defined(Q_OS_MACX) +#if defined(Q_OS_DARWIN) if (what & QFileSystemMetaData::BundleType) { if (entryExists && isPackage(data, entry)) data.entryFlags |= QFileSystemMetaData::BundleType; diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index da9576b5f8..828b5b329c 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -93,7 +93,7 @@ public: LinkType = 0x00010000, FileType = 0x00020000, DirectoryType = 0x00040000, -#if defined(Q_OS_MACX) +#if defined(Q_OS_DARWIN) BundleType = 0x00080000, AliasType = 0x08000000, #else @@ -243,7 +243,7 @@ private: Q_DECLARE_OPERATORS_FOR_FLAGS(QFileSystemMetaData::MetaDataFlags) -#if defined(Q_OS_MACX) +#if defined(Q_OS_DARWIN) inline bool QFileSystemMetaData::isBundle() const { return (entryFlags & BundleType); } inline bool QFileSystemMetaData::isAlias() const { return (entryFlags & AliasType); } #else diff --git a/src/corelib/io/qstorageinfo_mac.cpp b/src/corelib/io/qstorageinfo_mac.cpp index 1ef9983918..64ca6d7175 100644 --- a/src/corelib/io/qstorageinfo_mac.cpp +++ b/src/corelib/io/qstorageinfo_mac.cpp @@ -147,32 +147,24 @@ void QStorageInfoPrivate::retrieveUrlProperties(bool initRootPath) void QStorageInfoPrivate::retrieveLabel() { -#if !defined(Q_OS_IOS) - // deprecated since 10.8 - FSRef ref; - FSPathMakeRef(reinterpret_cast<const UInt8*>(QFile::encodeName(rootPath).constData()), - &ref, - Q_NULLPTR); - - // deprecated since 10.8 - FSCatalogInfo catalogInfo; - OSErr error; - error = FSGetCatalogInfo(&ref, kFSCatInfoVolume, &catalogInfo, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR); - if (error != noErr) + QCFString path = CFStringCreateWithFileSystemRepresentation(0, + QFile::encodeName(rootPath).constData()); + if (!path) return; - // deprecated (use CFURLCopyResourcePropertiesForKeys for 10.7 and higher) - HFSUniStr255 volumeName; - error = FSGetVolumeInfo(catalogInfo.volume, - 0, - Q_NULLPTR, - kFSVolInfoFSInfo, - Q_NULLPTR, - &volumeName, - Q_NULLPTR); - if (error == noErr) - name = QCFString(FSCreateStringFromHFSUniStr(Q_NULLPTR, &volumeName)); -#endif + QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, path, kCFURLPOSIXPathStyle, true); + if (!url) + return; + + QCFType<CFURLRef> volumeUrl; + if (!CFURLCopyResourcePropertyForKey(url, kCFURLVolumeURLKey, &volumeUrl, NULL)) + return; + + QCFString volumeName; + if (!CFURLCopyResourcePropertyForKey(url, kCFURLNameKey, &volumeName, NULL)) + return; + + name = volumeName; } QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes() |