summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
diff options
context:
space:
mode:
authorWang Fei <wangfeia@uniontech.com>2021-11-16 13:17:39 +0800
committerChristian Ehrlicher <ch.ehrlicher@gmx.de>2022-12-23 06:26:44 +0100
commit936cae6b53e8982fb087458745e06721d35341ef (patch)
tree75dfa407218049d42262f9da0430e94918c57ec8 /src/corelib/io
parent8844c6ef379f466a12a5f4981c78bdb990d92db8 (diff)
Add QFileInfo::readSymLink() to read the raw link path
The existing symLinkTarget() always resolves the symlink target to an absolute path; readSymLink() provides access to the relative path when that is how the symlink references its target. [ChangeLog][QtCore][QFileInfo] Added readSymLink() to read the symlink's raw target, without resolving to an absolute path. Fixes: QTBUG-96761 Change-Id: I360e55f1a3bdb00e2966229ea8de78cf29a29417 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/io')
-rw-r--r--src/corelib/io/qabstractfileengine.cpp2
-rw-r--r--src/corelib/io/qabstractfileengine_p.h1
-rw-r--r--src/corelib/io/qfileinfo.cpp22
-rw-r--r--src/corelib/io/qfileinfo.h4
-rw-r--r--src/corelib/io/qfilesystemengine_p.h2
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp10
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp19
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp6
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp2
-rw-r--r--src/corelib/io/qtemporaryfile.cpp2
10 files changed, 63 insertions, 7 deletions
diff --git a/src/corelib/io/qabstractfileengine.cpp b/src/corelib/io/qabstractfileengine.cpp
index 401eae8aa2..25dfe79d64 100644
--- a/src/corelib/io/qabstractfileengine.cpp
+++ b/src/corelib/io/qabstractfileengine.cpp
@@ -225,6 +225,8 @@ QAbstractFileEngine *QAbstractFileEngine::create(const QString &fileName)
the base name).
\value AbsoluteLinkTarget The full file name of the file that this file is a
link to. (This will be empty if this file is not a link.)
+ \value RawLinkPath The raw link path of the file that this file is a
+ link to. (This will be empty if this file is not a link.)
\value CanonicalName Often very similar to AbsoluteLinkTarget. Will return the true path to the file.
\value CanonicalPathName Same as CanonicalName, excluding the base name.
\value BundleName Returns the name of the bundle implies BundleType is set.
diff --git a/src/corelib/io/qabstractfileengine_p.h b/src/corelib/io/qabstractfileengine_p.h
index 04ad782763..28f07bf8f9 100644
--- a/src/corelib/io/qabstractfileengine_p.h
+++ b/src/corelib/io/qabstractfileengine_p.h
@@ -73,6 +73,7 @@ public:
CanonicalPathName,
BundleName,
JunctionName,
+ RawLinkPath,
NFileNames // Must be last.
};
enum FileOwner {
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 351fbc3d86..a9b35b78d4 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -38,6 +38,9 @@ QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const
case QAbstractFileEngine::AbsoluteLinkTarget:
ret = QFileSystemEngine::getLinkTarget(fileEntry, metaData).filePath();
break;
+ case QAbstractFileEngine::RawLinkPath:
+ ret = QFileSystemEngine::getRawLinkPath(fileEntry, metaData).filePath();
+ break;
case QAbstractFileEngine::JunctionName:
ret = QFileSystemEngine::getJunctionTarget(fileEntry, metaData).filePath();
break;
@@ -1222,6 +1225,25 @@ QString QFileInfo::symLinkTarget() const
}
/*!
+ \since 6.6
+ Read the path the symlink references.
+
+ Returns the raw path referenced by the symbolic link, without resolving a relative
+ path relative to the directory containing the symbolic link. The returned string will
+ only be an absolute path if the symbolic link actually references it as such. Returns
+ an empty string if the object is not a symbolic link.
+
+ \sa symLinkTarget(), exists(), isSymLink(), isDir(), isFile()
+*/
+QString QFileInfo::readSymLink() const
+{
+ Q_D(const QFileInfo);
+ if (d->isDefaultConstructed)
+ return {};
+ return d->getFileName(QAbstractFileEngine::RawLinkPath);
+}
+
+/*!
\since 6.2
Resolves an NTFS junction to the path it references.
diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h
index d0ec231f89..815659a7fe 100644
--- a/src/corelib/io/qfileinfo.h
+++ b/src/corelib/io/qfileinfo.h
@@ -126,12 +126,16 @@ public:
bool isBundle() const;
QString symLinkTarget() const;
+ QString readSymLink() const;
QString junctionTarget() const;
#if QT_CONFIG(cxx17_filesystem) || defined(Q_QDOC)
std::filesystem::path filesystemSymLinkTarget() const
{ return QtPrivate::toFilesystemPath(symLinkTarget()); }
+ std::filesystem::path filesystemReadSymLink() const
+ { return QtPrivate::toFilesystemPath(readSymLink()); }
+
std::filesystem::path filesystemJunctionTarget() const
{ return QtPrivate::toFilesystemPath(junctionTarget()); }
#endif // QT_CONFIG(cxx17_filesystem)
diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h
index c54efa7f63..c1dddb2e1e 100644
--- a/src/corelib/io/qfilesystemengine_p.h
+++ b/src/corelib/io/qfilesystemengine_p.h
@@ -67,6 +67,8 @@ public:
}
static QFileSystemEntry getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data);
+ static QFileSystemEntry getRawLinkPath(const QFileSystemEntry &link,
+ QFileSystemMetaData &data);
static QFileSystemEntry getJunctionTarget(const QFileSystemEntry &link, QFileSystemMetaData &data);
static QFileSystemEntry canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data);
static QFileSystemEntry absoluteName(const QFileSystemEntry &entry);
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index daa11ff6b2..f420a0086e 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -629,6 +629,16 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link,
}
//static
+QFileSystemEntry QFileSystemEngine::getRawLinkPath(const QFileSystemEntry &link,
+ QFileSystemMetaData &data)
+{
+ Q_UNUSED(data)
+ const QByteArray path = qt_readlink(link.nativeFilePath().constData());
+ const QString ret = QFile::decodeName(path);
+ return QFileSystemEntry(ret);
+}
+
+//static
QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data)
{
Q_CHECK_FILE_NAME(entry, entry);
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 6d085d98c9..9cfa1d7b7d 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -856,6 +856,18 @@ void QFileSystemEngine::clearWinStatData(QFileSystemMetaData &data)
QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link,
QFileSystemMetaData &data)
{
+ QFileSystemEntry ret = getRawLinkPath(link, data);
+ if (!ret.isEmpty() && ret.isRelative()) {
+ QString target = absoluteName(link).path() + u'/' + ret.filePath();
+ ret = QFileSystemEntry(QDir::cleanPath(target));
+ }
+ return ret;
+}
+
+//static
+QFileSystemEntry QFileSystemEngine::getRawLinkPath(const QFileSystemEntry &link,
+ QFileSystemMetaData &data)
+{
Q_CHECK_FILE_NAME(link, link);
if (data.missingFlags(QFileSystemMetaData::LinkType))
@@ -866,12 +878,7 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link,
target = readLink(link);
else if (data.isLink())
target = readSymLink(link);
- QFileSystemEntry ret(target);
- if (!target.isEmpty() && ret.isRelative()) {
- target.prepend(absoluteName(link).path() + u'/');
- ret = QFileSystemEntry(QDir::cleanPath(target));
- }
- return ret;
+ return QFileSystemEntry(target);
}
//static
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index a08feb73fb..d5a0a731d6 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -450,6 +450,12 @@ QString QFSFileEngine::fileName(FileName file) const
return entry.filePath();
}
return QString();
+ case RawLinkPath:
+ if (d->isSymlink()) {
+ QFileSystemEntry entry = QFileSystemEngine::getRawLinkPath(d->fileEntry, d->metaData);
+ return entry.filePath();
+ }
+ return QString();
case JunctionName:
return QString();
case DefaultName:
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index 1030c55937..daa4326212 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -619,6 +619,8 @@ QString QFSFileEngine::fileName(FileName file) const
}
case AbsoluteLinkTarget:
return QFileSystemEngine::getLinkTarget(d->fileEntry, d->metaData).filePath();
+ case RawLinkPath:
+ return QFileSystemEngine::getRawLinkPath(d->fileEntry, d->metaData).filePath();
case BundleName:
return QString();
case JunctionName:
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index 86ad1439e3..13f2e447e7 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -406,7 +406,7 @@ bool QTemporaryFileEngine::close()
QString QTemporaryFileEngine::fileName(QAbstractFileEngine::FileName file) const
{
if (isUnnamedFile()) {
- if (file == AbsoluteLinkTarget) {
+ if (file == AbsoluteLinkTarget || file == RawLinkPath) {
// we know our file isn't (won't be) a symlink
return QString();
}