diff options
author | Thomas Zander <t.zander@nokia.com> | 2010-09-03 13:27:58 (GMT) |
---|---|---|
committer | Thomas Zander <t.zander@nokia.com> | 2010-09-06 13:21:00 (GMT) |
commit | 8f6f2adc2a8eee620bfe342f211035948a3fedc8 (patch) | |
tree | 897ee0ffbba3e4843a1b650887732f854427fa74 /src/corelib/io | |
parent | d1e1f1e83142f18d75c323b44a094d4df6762a3a (diff) | |
download | Qt-8f6f2adc2a8eee620bfe342f211035948a3fedc8.zip Qt-8f6f2adc2a8eee620bfe342f211035948a3fedc8.tar.gz Qt-8f6f2adc2a8eee620bfe342f211035948a3fedc8.tar.bz2 |
Move resolving a symlink to the qfilesystemengine_unix
Reviewed-by: João Abecasis
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qfilesystemengine_p.h | 2 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_unix.cpp | 74 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_win.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_unix.cpp | 70 |
4 files changed, 76 insertions, 72 deletions
diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index 990a5ff..94fb4e5 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -64,7 +64,7 @@ class QFileSystemEngine public: static bool isCaseSensitive(); - static QFileSystemEntry getLinkTarget(const QFileSystemEntry &link); + static QFileSystemEntry getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data); static QFileSystemEntry canonicalName(const QFileSystemEntry &entry); static QFileSystemEntry absoluteName(const QFileSystemEntry &entry); diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 6b3c157..755298d 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -163,9 +163,79 @@ bool QFileSystemEngine::isCaseSensitive() } //static -QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link) +QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data) { - return link; // TODO implement +#if defined(__GLIBC__) && !defined(PATH_MAX) +#define PATH_CHUNK_SIZE 256 + char *s = 0; + int len = -1; + int size = PATH_CHUNK_SIZE; + + while (1) { + s = (char *) ::realloc(s, size); + Q_CHECK_PTR(s); + len = ::readlink(link.nativeFilePath().constData(), s, size); + if (len < 0) { + ::free(s); + break; + } + if (len < size) { + break; + } + size *= 2; + } +#else + char s[PATH_MAX+1]; + int len = readlink(link.nativeFilePath().constData(), s, PATH_MAX); +#endif + if (len > 0) { + QString ret; + if (!data.hasFlags(QFileSystemMetaData::DirectoryType)) + fillMetaData(link, data, QFileSystemMetaData::DirectoryType); + if (data.isDirectory() && s[0] != '/') { + QDir parent(link.filePath()); + parent.cdUp(); + ret = parent.path(); + if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) + ret += QLatin1Char('/'); + } + s[len] = '\0'; + ret += QFile::decodeName(QByteArray(s)); +#if defined(__GLIBC__) && !defined(PATH_MAX) + ::free(s); +#endif + + if (!ret.startsWith(QLatin1Char('/'))) { + if (link.filePath().startsWith(QLatin1Char('/'))) { + ret.prepend(link.filePath().left(link.filePath().lastIndexOf(QLatin1Char('/'))) + + QLatin1Char('/')); + } else { + ret.prepend(QDir::currentPath() + QLatin1Char('/')); + } + } + ret = QDir::cleanPath(ret); + if (ret.size() > 1 && ret.endsWith(QLatin1Char('/'))) + ret.chop(1); + return QFileSystemEntry(ret); + } +#if !defined(QWS) && defined(Q_OS_MAC) + { + 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)); + } + } + } + } +#endif + return QFileSystemEntry(); } //static diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index ef47fe5..8572506 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -49,7 +49,7 @@ bool QFileSystemEngine::isCaseSensitive() } //static -QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link) +QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data) { return link; // TODO implement } diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 71a604a..c7df5ed 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -861,75 +861,9 @@ QString QFSFileEngine::fileName(FileName file) const return entry.filePath(); } else if (file == LinkName) { if (d->isSymlink()) { -#if defined(__GLIBC__) && !defined(PATH_MAX) -#define PATH_CHUNK_SIZE 256 - char *s = 0; - int len = -1; - int size = PATH_CHUNK_SIZE; - - while (1) { - s = (char *) ::realloc(s, size); - Q_CHECK_PTR(s); - len = ::readlink(d->fileEntry.nativeFilePath().constData(), s, size); - if (len < 0) { - ::free(s); - break; - } - if (len < size) { - break; - } - size *= 2; - } -#else - char s[PATH_MAX+1]; - int len = readlink(d->fileEntry.nativeFilePath().constData(), s, PATH_MAX); -#endif - if (len > 0) { - QString ret; - if (d->doStat(QFileSystemMetaData::DirectoryType) - && d->metaData.isDirectory() && s[0] != '/') { - QDir parent(d->fileEntry.filePath()); - parent.cdUp(); - ret = parent.path(); - if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) - ret += QLatin1Char('/'); - } - s[len] = '\0'; - ret += QFile::decodeName(QByteArray(s)); -#if defined(__GLIBC__) && !defined(PATH_MAX) - ::free(s); -#endif - - if (!ret.startsWith(QLatin1Char('/'))) { - if (d->fileEntry.filePath().startsWith(QLatin1Char('/'))) { - ret.prepend(d->fileEntry.filePath().left(d->fileEntry.filePath().lastIndexOf(QLatin1Char('/'))) - + QLatin1Char('/')); - } else { - ret.prepend(QDir::currentPath() + QLatin1Char('/')); - } - } - ret = QDir::cleanPath(ret); - if (ret.size() > 1 && ret.endsWith(QLatin1Char('/'))) - ret.chop(1); - return ret; - } + QFileSystemEntry entry = QFileSystemEngine::getLinkTarget(d->fileEntry, d->metaData); + return entry.filePath(); } -#if !defined(QWS) && defined(Q_OS_MAC) - { - FSRef fref; - if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->fileEntry.filePath())).data(), &fref, 0) == noErr) { - 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 QCFString::toQString(cfstr); - } - } - } - } -#endif return QString(); } return d->fileEntry.filePath(); |