summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
diff options
context:
space:
mode:
authorJake Petroules <jake.petroules@theqtcompany.com>2015-07-13 20:16:44 -0700
committerJake Petroules <jake.petroules@theqtcompany.com>2015-09-22 00:09:20 +0000
commit46a372e1a115fb05b746339c790a7f3e5d6d01fc (patch)
treeac26264e5d38a3c6e3c4389c38db7351f1a9731c /src/corelib/io
parent827d0c023222c58443bd825c6287949a2cc07de7 (diff)
Modernize and unify filesystem code on Apple platforms.
Replace deprecated File Manager APIs with modern equivalents. Change some Q_OS_MACX to Q_OS_DARWIN in file system related code. All of these apply to iOS as well as OS X, and were ifdef'ed for OS X only primarily due to legacy reasons - carryovers from Qt 4 or Carbon APIs which have since been refactored into using CoreFoundation. This also makes the code consistent with the documentation. Change-Id: I414e9bdfffff731413ddf16171b1317027d87caf Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@theqtcompany.com>
Diffstat (limited to 'src/corelib/io')
-rw-r--r--src/corelib/io/io.pri1
-rw-r--r--src/corelib/io/qfilesystemengine.cpp2
-rw-r--r--src/corelib/io/qfilesystemengine_p.h2
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp161
-rw-r--r--src/corelib/io/qfilesystemmetadata_p.h4
-rw-r--r--src/corelib/io/qstorageinfo_mac.cpp40
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()