summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qcoreapplication.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qcoreapplication.cpp')
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp102
1 files changed, 63 insertions, 39 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index aea82fd48b..18a379f8b9 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -10,9 +10,9 @@
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@@ -48,7 +48,6 @@
#include <qhash.h>
#include <qmutex.h>
#include <private/qloggingregistry_p.h>
-#include <private/qprocess_p.h>
#include <qstandardpaths.h>
#include <qtextcodec.h>
#ifndef QT_NO_QOBJECT
@@ -323,7 +322,7 @@ QCoreApplication *QCoreApplication::self = 0;
uint QCoreApplicationPrivate::attribs = (1 << Qt::AA_SynthesizeMouseForUnhandledTouchEvents);
struct QCoreApplicationData {
- QCoreApplicationData() {
+ QCoreApplicationData() Q_DECL_NOTHROW {
#ifndef QT_NO_LIBRARY
app_libpaths = 0;
#endif
@@ -384,6 +383,34 @@ Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
static bool quitLockRefEnabled = true;
#endif
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+// Check whether the command line arguments match those passed to main()
+// by comparing to the global __argv/__argc (MS extension).
+// Deep comparison is required since argv/argc is rebuilt by WinMain for
+// GUI apps or when using MinGW due to its globbing.
+static inline bool isArgvModified(int argc, char **argv)
+{
+ if (__argc != argc)
+ return true;
+ if (__argv == argv)
+ return false;
+ for (int a = 0; a < argc; ++a) {
+ if (argv[a] != __argv[a] && strcmp(argv[a], __argv[a]))
+ return true;
+ }
+ return false;
+}
+
+static inline bool contains(int argc, char **argv, const char *needle)
+{
+ for (int a = 0; a < argc; ++a) {
+ if (!strcmp(argv[a], needle))
+ return true;
+ }
+ return false;
+}
+#endif // Q_OS_WIN && !Q_OS_WINRT
+
QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint flags)
:
#ifndef QT_NO_QOBJECT
@@ -391,9 +418,9 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
#endif
argc(aargc)
, argv(aargv)
-#ifdef Q_OS_WIN
- , origArgc(aargc)
- , origArgv(new char *[aargc])
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+ , origArgc(0)
+ , origArgv(Q_NULLPTR)
#endif
, application_type(QCoreApplicationPrivate::Tty)
#ifndef QT_NO_QOBJECT
@@ -410,9 +437,13 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
argc = 0;
argv = (char **)&empty;
}
-#ifdef Q_OS_WIN
- std::copy(argv, argv + argc, origArgv);
-#endif
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+ if (!isArgvModified(argc, argv)) {
+ origArgc = argc;
+ origArgv = new char *[argc];
+ std::copy(argv, argv + argc, origArgv);
+ }
+#endif // Q_OS_WIN && !Q_OS_WINRT
#ifndef QT_NO_QOBJECT
QCoreApplicationPrivate::is_app_closing = false;
@@ -437,7 +468,7 @@ QCoreApplicationPrivate::~QCoreApplicationPrivate()
#ifndef QT_NO_QOBJECT
cleanupThreadData();
#endif
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
delete [] origArgv;
#endif
QCoreApplicationPrivate::clearApplicationFilePath();
@@ -744,14 +775,6 @@ void QCoreApplication::init()
d->appendApplicationPathToLibraryPaths();
#endif
-#ifndef QT_NO_QOBJECT
-#if defined(Q_OS_UNIX) && !(defined(QT_NO_PROCESS))
- // Make sure the process manager thread object is created in the main
- // thread.
- QProcessPrivate::initializeProcessManager();
-#endif
-#endif
-
#ifdef QT_EVAL
extern void qt_core_eval_init(QCoreApplicationPrivate::Type);
qt_core_eval_init(d->application_type);
@@ -2158,10 +2181,11 @@ qint64 QCoreApplication::applicationPid()
Latin1 locale. Most modern Unix systems do not have this limitation, as they are
Unicode-based.
- On NT-based Windows, this limitation does not apply either.
- On Windows, the arguments() are not built from the contents of argv/argc, as
- the content does not support Unicode. Instead, the arguments() are constructed
- from the return value of
+ On Windows, the list is built from the argc and argv parameters only if
+ modified argv/argc parameters are passed to the constructor. In that case,
+ encoding problems might occur.
+
+ Otherwise, the arguments() are constructed from the return value of
\l{http://msdn2.microsoft.com/en-us/library/ms683156(VS.85).aspx}{GetCommandLine()}.
As a result of this, the string given by arguments().at(0) might not be
the program name on Windows, depending on how the application was started.
@@ -2196,21 +2220,21 @@ QStringList QCoreApplication::arguments()
}
#endif // Q_OS_WINCE
- char ** const origArgv = self->d_func()->origArgv;
- const int origArgc = self->d_func()->origArgc;
- char ** const avEnd = av + ac;
-
- const QStringList allArguments = qWinCmdArgs(cmdline);
- Q_ASSERT(allArguments.size() == origArgc);
- for (int i = 0; i < origArgc; ++i)
- if (std::find(av, avEnd, origArgv[i]) != avEnd)
- list.push_back(allArguments.at(i));
+ const QCoreApplicationPrivate *d = self->d_func();
+ if (d->origArgv) {
+ const QStringList allArguments = qWinCmdArgs(cmdline);
+ Q_ASSERT(allArguments.size() == d->origArgc);
+ for (int i = 0; i < d->origArgc; ++i) {
+ if (contains(ac, av, d->origArgv[i]))
+ list.append(allArguments.at(i));
+ }
+ return list;
+ } // Fall back to rebuilding from argv/argc when a modified argv was passed.
+#endif // defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
-#else
for (int a = 0; a < ac; ++a) {
list << QString::fromLocal8Bit(av[a]);
}
-#endif
return list;
}