summaryrefslogtreecommitdiffstats
path: root/src/sdk/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sdk/main.cpp')
-rw-r--r--src/sdk/main.cpp87
1 files changed, 82 insertions, 5 deletions
diff --git a/src/sdk/main.cpp b/src/sdk/main.cpp
index a2eb22189..abfc9dc5a 100644
--- a/src/sdk/main.cpp
+++ b/src/sdk/main.cpp
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -38,13 +38,23 @@
#include <utils.h>
#include <loggingutils.h>
+#ifdef IFW_LIB7Z
+#include <7zVersion.h>
+#endif
+#ifdef IFW_LIBARCHIVE
+#include <archive.h>
+#endif
+
#include <QCommandLineParser>
#include <QDateTime>
#include <QNetworkProxyFactory>
+#include <QThread>
+#include <QThreadPool>
+#include <QDeadlineTimer>
#include <iostream>
-#if defined(Q_OS_MACOS) or defined(Q_OS_UNIX)
+#if defined(Q_OS_MACOS) || defined(Q_OS_UNIX)
# include <unistd.h>
# include <sys/types.h>
#endif
@@ -56,8 +66,47 @@
#define SHA "Installer Framework SHA1: " QUOTE(_GIT_SHA1_)
static const char PLACEHOLDER[32] = "MY_InstallerCreateDateTime_MY";
+#ifdef Q_OS_WIN
+static void cleanupUpdate(const CommandLineParser &parser, bool *exit)
+{
+ QString cleanupPath;
+ QString cleanupOption;
+ *exit = false;
+
+ if (parser.isSet(CommandLineOptions::scCleanupUpdate)) {
+ cleanupPath = parser.value(CommandLineOptions::scCleanupUpdate);
+ cleanupOption = CommandLineOptions::scCleanupUpdate;
+ } else if (parser.isSet(CommandLineOptions::scCleanupUpdateOnly)) {
+ cleanupPath = parser.value(CommandLineOptions::scCleanupUpdateOnly);
+ cleanupOption = CommandLineOptions::scCleanupUpdateOnly;
+ *exit = true;
+ }
+
+ if (cleanupOption.isEmpty())
+ return;
+
+ // Since Windows does not support that the maintenance tool deletes itself we
+ // remove the old executable here after update (as the new maintenance tool).
+ if (!cleanupPath.isEmpty()) {
+ QFile fileToRemove(cleanupPath);
+ // Give up after 120 seconds if the old process has not exited and released the file
+ QDeadlineTimer deadline(120000);
+ while (fileToRemove.exists() && !deadline.hasExpired()) {
+ if (fileToRemove.remove()) {
+ std::cout << "Removed leftover file: " << qPrintable(cleanupPath)
+ << " after update." << std::endl;
+ }
+ QThread::msleep(1000);
+ }
+ } else {
+ std::cout << "Invalid value for option " << qPrintable(cleanupOption);
+ }
+}
+#endif
+
int main(int argc, char *argv[])
{
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
if (!qEnvironmentVariableIsSet("QT_AUTO_SCREEN_SCALE_FACTOR")
&& !qEnvironmentVariableIsSet("QT_SCALE_FACTOR")
&& !qEnvironmentVariableIsSet("QT_SCREEN_SCALE_FACTORS")) {
@@ -66,6 +115,7 @@ int main(int argc, char *argv[])
#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton);
#endif
+#endif
// increase maximum numbers of file descriptors
#if defined(Q_OS_MACOS)
QCoreApplication::setSetuidAllowed(true);
@@ -75,6 +125,13 @@ int main(int argc, char *argv[])
setrlimit(RLIMIT_NOFILE, &rl);
#endif
+ // Try to avoid running into situations where the application would hang due to "nested" blocking
+ // usage of the global threadpool that has only one thread available, i.e. main thread invokes
+ // QtConcurrent::run(&myFunction) and myFunction() calls QtConcurrent::blockingFiltered()
+ // for a container.
+ if (QThread::idealThreadCount() == 1)
+ QThreadPool::globalInstance()->setMaxThreadCount(2);
+
// We need to start either a command line application or a GUI application. Since we
// fail doing so at least on Linux while parsing the argument using a core application
// object and later starting the GUI application, we now parse the arguments first.
@@ -112,8 +169,10 @@ int main(int argc, char *argv[])
.arg(mutually.join(QLatin1String(", ")));
sanityCheck = false;
}
- const QSet<QString> commands = parser.positionalArguments().toSet()
- .intersect(CommandLineOptions::scCommandLineInterfaceOptions.toSet());
+ const QStringList positionalArgs = parser.positionalArguments();
+ QSet<QString> commands(positionalArgs.begin(), positionalArgs.end());
+ commands.intersect(QSet<QString>(CommandLineOptions::scCommandLineInterfaceOptions.begin(),
+ CommandLineOptions::scCommandLineInterfaceOptions.end()));
// Check sanity of the given argument sequence.
if (commands.size() > 1) {
sanityMessage = QString::fromLatin1("%1 commands provided, only one can be used at a time.")
@@ -130,6 +189,12 @@ int main(int argc, char *argv[])
if (parser.isSet(CommandLineOptions::scVersionLong)) {
std::cout << VERSION << std::endl << BUILDDATE << std::endl << SHA << std::endl;
+#ifdef IFW_LIB7Z
+ std::cout << "LZMA SDK version: " << MY_VERSION << std::endl;
+#endif
+#ifdef IFW_LIBARCHIVE
+ std::cout << "Libarchive version: " << archive_version_details() << std::endl;
+#endif
const QDateTime dateTime = QDateTime::fromString(QLatin1String(PLACEHOLDER),
QLatin1String("yyyy-MM-dd - HH:mm:ss"));
if (dateTime.isValid())
@@ -144,9 +209,18 @@ int main(int argc, char *argv[])
return help ? EXIT_SUCCESS : EXIT_FAILURE;
}
+#ifdef Q_OS_WIN
+ {
+ bool exit = false;
+ cleanupUpdate(parser, &exit);
+ if (exit)
+ return EXIT_SUCCESS;
+ }
+#endif
+
if (parser.isSet(CommandLineOptions::scStartServerLong)) {
const QStringList arguments = parser.value(CommandLineOptions::scStartServerLong)
- .split(QLatin1Char(','), QString::SkipEmptyParts);
+ .split(QLatin1Char(','), Qt::SkipEmptyParts);
QString socketName, key;
const QString mode = arguments.value(0);
@@ -267,6 +341,9 @@ int main(int argc, char *argv[])
} else if (parser.positionalArguments().contains(CommandLineOptions::scCreateOfflineShort)
|| parser.positionalArguments().contains(CommandLineOptions::scCreateOfflineLong)) {
return CommandLineInterface(argc, argv).createOfflineInstaller();
+ } else if (parser.positionalArguments().contains(CommandLineOptions::scClearCacheShort)
+ || parser.positionalArguments().contains(CommandLineOptions::scClearCacheLong)) {
+ return CommandLineInterface(argc, argv).clearLocalCache();
}
if (QInstaller::LoggingHandler::instance().isVerbose()) {
std::cout << VERSION << std::endl << BUILDDATE << std::endl << SHA << std::endl;