Blackberry: Fix QCoreApplication::applicationFilePath() performance.
authorSergio Martins <sergio.martins.qnx@kdab.com>
Thu, 25 Oct 2012 16:50:47 +0000 (17:50 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Fri, 2 Nov 2012 17:07:35 +0000 (18:07 +0100)
Listing all files with QDir is slow.
Instead, use argv[0] for zygotized apps and _cmdname() for
non-zygotized.

Apps run through the terminal will fall in the zygotized case,
which is ok.

Note about zygotized apps:
  Zygotized apps don't have an executable, they live in a shared
  object file.

  These apps are run through a deamon that forks and dlopens()
  the shared object ( for performance reasons ).

  For this reason we can't use _cmdname(), since it just contains
  the the file path of the daemon.

  On the other hand, non-zygotized apps have a bogus argv[0]
  when run through the navigator ( command line is fine ).

Change-Id: I9953e8fa05c9fb11c33b3a38ebab00fe33ba4c44
Reviewed-by: Kevin Krammer <kevin.krammer@kdab.com>
Reviewed-by: Thomas McGuire <thomas.mcguire@kdab.com>
src/corelib/kernel/qcoreapplication.cpp

index 590d127..2575f0b 100644 (file)
@@ -69,6 +69,8 @@
 #if defined(Q_OS_UNIX)
 #  if defined(Q_OS_BLACKBERRY)
 #    include "qeventdispatcher_blackberry_p.h"
+#    include <process.h>
+#    include <unistd.h>
 #  else
 #    if !defined(QT_NO_GLIB)
 #      include "qeventdispatcher_glib_p.h"
@@ -1805,11 +1807,34 @@ QString QCoreApplication::applicationFilePath()
     d->cachedApplicationFilePath = QFileInfo(qAppFileName()).filePath();
     return d->cachedApplicationFilePath;
 #elif defined(Q_OS_BLACKBERRY)
-    QDir dir(QStringLiteral("./app/native/"));
-    QStringList executables = dir.entryList(QDir::Executable | QDir::Files);
-    if (!executables.empty()) {
-        //We assume that there is only one executable in the folder
-        return dir.absoluteFilePath(executables.first());
+    if (!arguments().isEmpty()) { // args is never empty, but the navigator can change behaviour some day
+        QFileInfo fileInfo(arguments().at(0));
+        const bool zygotized = fileInfo.exists();
+        if (zygotized) {
+            // Handle the zygotized case:
+            d->cachedApplicationFilePath = QDir::cleanPath(fileInfo.absoluteFilePath());
+            return d->cachedApplicationFilePath;
+        }
+    }
+
+    // Handle the non-zygotized case:
+    const size_t maximum_path = static_cast<size_t>(pathconf("/",_PC_PATH_MAX));
+    char buff[maximum_path+1];
+    if (_cmdname(buff)) {
+        d->cachedApplicationFilePath = QDir::cleanPath(QString::fromLocal8Bit(buff));
+        return d->cachedApplicationFilePath;
+    } else {
+        qWarning("QCoreApplication::applicationFilePath: _cmdname() failed");
+        // _cmdname() won't fail, but just in case, fallback to the old method
+        QDir dir(QStringLiteral("./app/native/"));
+        QStringList executables = dir.entryList(QDir::Executable | QDir::Files);
+        if (!executables.empty()) {
+            //We assume that there is only one executable in the folder
+            d->cachedApplicationFilePath = dir.absoluteFilePath(executables.first());
+            return d->cachedApplicationFilePath;
+        } else {
+            return QString();
+        }
     }
 #elif defined(Q_OS_MAC)
     QString qAppFileName_str = qAppFileName();