summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2017-06-30 13:30:52 -0700
committerThiago Macieira <thiago.macieira@intel.com>2017-07-08 02:18:16 +0000
commit80c152d6898c1b8727ac14d32437b274153a7089 (patch)
tree78d2b98bac5cd3e6a4395e8e86ce7fb68f3ec0fa /src
parent3c689c4b3fd24ead8726444723536452d0e89d85 (diff)
Move the readlink(2) wrapper to qcore_unix.cpp
This deduplicates the code between QFileSystemEngine and QLockFile. Change-Id: I1eba2b016de74620bfc8fffd14cd005d5fd9beaa Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp33
-rw-r--r--src/corelib/io/qlockfile_unix.cpp8
-rw-r--r--src/corelib/kernel/qcore_unix.cpp33
-rw-r--r--src/corelib/kernel/qcore_unix_p.h2
-rw-r--r--src/tools/bootstrap/bootstrap.pro3
5 files changed, 45 insertions, 34 deletions
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index 929db259ec..2c8c4e8f9e 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -44,6 +44,7 @@
#include "qfile.h"
#include <QtCore/qoperatingsystemversion.h>
+#include <QtCore/private/qcore_unix_p.h>
#include <QtCore/qvarlengtharray.h>
#include <stdlib.h> // for realpath()
@@ -150,30 +151,8 @@ static bool isPackage(const QFileSystemMetaData &data, const QFileSystemEntry &e
//static
QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data)
{
-#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) {
+ QByteArray s = qt_readlink(link.nativeFilePath().constData());
+ if (s.length() > 0) {
QString ret;
if (!data.hasFlags(QFileSystemMetaData::DirectoryType))
fillMetaData(link, data, QFileSystemMetaData::DirectoryType);
@@ -184,11 +163,7 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link,
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
+ ret += QFile::decodeName(s);
if (!ret.startsWith(QLatin1Char('/'))) {
const QString linkFilePath = link.filePath();
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp
index f21aced87c..1ee8ce889c 100644
--- a/src/corelib/io/qlockfile_unix.cpp
+++ b/src/corelib/io/qlockfile_unix.cpp
@@ -260,15 +260,15 @@ QString QLockFilePrivate::processNameByPid(qint64 pid)
#elif defined(Q_OS_LINUX)
if (!qt_haveLinuxProcfs())
return QString();
+
char exePath[64];
- char buf[PATH_MAX + 1];
sprintf(exePath, "/proc/%lld/exe", pid);
- size_t len = (size_t)readlink(exePath, buf, sizeof(buf));
- if (len >= sizeof(buf)) {
+
+ QByteArray buf = qt_readlink(exePath);
+ if (buf.isEmpty()) {
// The pid is gone. Return some invalid process name to fail the test.
return QStringLiteral("/ERROR/");
}
- buf[len] = 0;
return QFileInfo(QFile::decodeName(buf)).fileName();
#elif defined(Q_OS_HAIKU)
thread_info info;
diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp
index 686143f8c7..3b0da136ca 100644
--- a/src/corelib/kernel/qcore_unix.cpp
+++ b/src/corelib/kernel/qcore_unix.cpp
@@ -50,6 +50,37 @@
QT_BEGIN_NAMESPACE
+QByteArray qt_readlink(const char *path)
+{
+#ifndef PATH_MAX
+ // suitably large value that won't consume too much memory
+# define PATH_MAX 1024*1024
+#endif
+
+ QByteArray buf(256, Qt::Uninitialized);
+
+ ssize_t len = ::readlink(path, buf.data(), buf.size());
+ while (len == buf.size()) {
+ // readlink(2) will fill our buffer and not necessarily terminate with NUL;
+ if (buf.size() >= PATH_MAX) {
+ errno = ENAMETOOLONG;
+ return QByteArray();
+ }
+
+ // double the size and try again
+ buf.resize(buf.size() * 2);
+ len = ::readlink(path, buf.data(), buf.size());
+ }
+
+ if (len == -1)
+ return QByteArray();
+
+ buf.resize(len);
+ return buf;
+}
+
+#ifndef QT_BOOTSTRAPPED
+
#if QT_CONFIG(poll_pollts)
# define ppoll pollts
#endif
@@ -121,4 +152,6 @@ int qt_safe_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout
}
}
+#endif // QT_BOOTSTRAPPED
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index ea5d98cbf3..9d2c4f6c31 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -55,6 +55,7 @@
#include <QtCore/private/qglobal_p.h>
#include "qplatformdefs.h"
#include "qatomic.h"
+#include "qbytearray.h"
#ifndef Q_OS_UNIX
# error "qcore_unix_p.h included on a non-Unix system"
@@ -339,6 +340,7 @@ static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options)
// in qelapsedtimer_mac.cpp or qtimestamp_unix.cpp
timespec qt_gettime() Q_DECL_NOTHROW;
void qt_nanosleep(timespec amount);
+QByteArray qt_readlink(const char *path);
/* non-static */
inline bool qt_haveLinuxProcfs()
diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro
index b92e5bb82b..8882df9fc5 100644
--- a/src/tools/bootstrap/bootstrap.pro
+++ b/src/tools/bootstrap/bootstrap.pro
@@ -94,7 +94,8 @@ SOURCES += \
../../xml/dom/qdom.cpp \
../../xml/sax/qxml.cpp
-unix:SOURCES += ../../corelib/io/qfilesystemengine_unix.cpp \
+unix:SOURCES += ../../corelib/kernel/qcore_unix.cpp \
+ ../../corelib/io/qfilesystemengine_unix.cpp \
../../corelib/io/qfilesystemiterator_unix.cpp \
../../corelib/io/qfsfileengine_unix.cpp