From 91882497952ebf33a76888b79125ce9cd56994d3 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Mon, 1 Jun 2015 11:25:31 +0200 Subject: [PATCH 01/27] Parse additional config files Some runtime settings need to be applied to the environment. Additional config files may be located in /tmp/b2qt/appcontroller.config.d or /var/lib/b2qt/appcontroller.config.d Task-number: QTEE-931 Change-Id: Id6c8c5695e6ca74351c7f81a66aa9a75a948792a Reviewed-by: Ulf Hermann --- main.cpp | 58 ++++++++++++++++++++++++++++++++++++------------------- process.h | 2 +- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/main.cpp b/main.cpp index fb52564..0f3486e 100644 --- a/main.cpp +++ b/main.cpp @@ -20,6 +20,7 @@ #include "portlist.h" #include "perfprocesshandler.h" #include +#include #include #include #include @@ -160,21 +161,13 @@ static int findFirstFreePort(Utils::PortList &range) return openServer(&s, range); } -static Config parseConfigFile() +static bool parseConfigFile(Config *config, const QString &fileName) { - Config config; - config.base = config.platform = QLatin1String("unknown"); - config.debugInterface = Config::LocalDebugInterface; - -#ifdef Q_OS_ANDROID - QFile f("/system/bin/appcontroller.conf"); -#else - QFile f("/etc/appcontroller.conf"); -#endif + QFile f(fileName); if (!f.open(QFile::ReadOnly)) { - fprintf(stderr, "Could not read config file.\n"); - return config; + fprintf(stderr, "Could not read config file: %s\n", qPrintable(fileName)); + return false; } while (!f.atEnd()) { @@ -185,27 +178,44 @@ static Config parseConfigFile() if (index < 2) { // ignore } else - config.env[sub.left(index)] = sub.mid(index+1); + config->env[sub.left(index)] = sub.mid(index+1); } else if (line.startsWith("append=")) { - config.args += line.mid(7).simplified(); + config->args += line.mid(7).simplified(); } else if (line.startsWith("base=")) { - config.base = line.mid(5).simplified(); + config->base = line.mid(5).simplified(); } else if (line.startsWith("platform=")) { - config.platform = line.mid(9).simplified(); + config->platform = line.mid(9).simplified(); } else if (line.startsWith("debugInterface=")) { const QString value = line.mid(15).simplified(); if (value == "local") - config.debugInterface = Config::LocalDebugInterface; + config->debugInterface = Config::LocalDebugInterface; else if (value == "public") - config.debugInterface = Config::PublicDebugInterface; + config->debugInterface = Config::PublicDebugInterface; else qWarning() << "Unkonwn value for debuginterface:" << value; } } f.close(); - return config; + return true; } +static bool parseConfigFileDirectory(Config *config, const QString &dirName) +{ + QDir d(dirName); + if (d.exists()) { + foreach (const QString &fileName, d.entryList(QDir::Files)) { + const QString file(d.absoluteFilePath(fileName)); + + if (!parseConfigFile(config, file)) { + fprintf(stderr, "Failed to parse config file: %s\n", qPrintable(file)); + return false; + } + } + } + return true; +} + + static bool removeDefault() { if (QFile::exists(B2QT_PREFIX)) { @@ -283,7 +293,15 @@ int main(int argc, char **argv) return 1; } - Config config = parseConfigFile(); + Config config; + if (!parseConfigFile(&config, "/etc/appcontroller.conf")) { + fprintf(stderr, "Failed to parse config file.\n"); + return 1; + } + + // Parse temporary config files + parseConfigFileDirectory(&config, "/var/lib/b2qt/appcontroller.conf.d"); + parseConfigFileDirectory(&config, "/tmp/b2qt/appcontroller.conf.d"); while (!args.isEmpty()) { const QString arg(args.takeFirst()); diff --git a/process.h b/process.h index bf67d96..d175dd3 100644 --- a/process.h +++ b/process.h @@ -37,7 +37,7 @@ struct Config { PublicDebugInterface }; - Config() : flags(0) { } + Config() : platform("unknown"), flags(0), debugInterface(LocalDebugInterface) { } QString base; QString platform; From 281140ecdd07fbc48f0bf45d395eedaf6a59fb2f Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 3 Jun 2015 09:38:16 +0200 Subject: [PATCH 02/27] Fix compile warnings Change-Id: I05fb9bca47f5bcfc3f127eb9a60e6be8bda8193a Reviewed-by: Ulf Hermann --- main.cpp | 3 ++- process.cpp | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/main.cpp b/main.cpp index 0f3486e..5c47dcf 100644 --- a/main.cpp +++ b/main.cpp @@ -433,7 +433,8 @@ int main(int argc, char **argv) } setsid(); - chdir("/"); + if (chdir("/") != 0) + return -1; signal(SIGHUP, SIG_IGN); // child diff --git a/process.cpp b/process.cpp index 1fe811b..7842deb 100644 --- a/process.cpp +++ b/process.cpp @@ -129,8 +129,9 @@ void Process::forwardProcessOutput(qintptr fd, const QByteArray &data) fd_set inputFdSet; FD_ZERO(&inputFdSet); FD_SET(pipefd[0], &inputFdSet); - if (select(qMax(fd, pipefd[0]) + 1, &inputFdSet, &outputFdSet, NULL, NULL) > 0 && - !FD_ISSET(pipefd[0], &inputFdSet)) + if (select(qMax(fd, static_cast(pipefd[0])) + 1, + &inputFdSet, &outputFdSet, NULL, NULL) > 0 && + !FD_ISSET(pipefd[0], &inputFdSet)) continue; // else fprintf below will output the appropriate errno } From f055f3c9fe5825f09af54ef4ccc2b24ae0181c22 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 3 Jun 2015 09:38:51 +0200 Subject: [PATCH 03/27] Ignore missing default config file Change-Id: Ieb219833bba906bdca1c8bd1dce18185d86ded86 Reviewed-by: Ulf Hermann --- main.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/main.cpp b/main.cpp index 5c47dcf..1e64c55 100644 --- a/main.cpp +++ b/main.cpp @@ -294,10 +294,8 @@ int main(int argc, char **argv) } Config config; - if (!parseConfigFile(&config, "/etc/appcontroller.conf")) { + if (!parseConfigFile(&config, "/etc/appcontroller.conf")) fprintf(stderr, "Failed to parse config file.\n"); - return 1; - } // Parse temporary config files parseConfigFileDirectory(&config, "/var/lib/b2qt/appcontroller.conf.d"); From 866aa6f727c096feada0f1d39cce44ca660ad787 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 3 Jun 2015 09:37:54 +0200 Subject: [PATCH 04/27] Send command string between appcontroller instances Task-number: QTEE-931 Change-Id: If0efdafdd5e39523d315be86cda07f69e2387e16 Reviewed-by: Ulf Hermann --- main.cpp | 50 +++++++++++++++++++++++++++++++------------------- process.cpp | 30 ++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/main.cpp b/main.cpp index 1e64c55..06bf501 100644 --- a/main.cpp +++ b/main.cpp @@ -21,6 +21,7 @@ #include "perfprocesshandler.h" #include #include +#include #include #include #include @@ -73,28 +74,39 @@ static void setupAddressStruct(struct sockaddr_un &address) address.sun_path[0] = 0; } -static int connectSocket() +static int connectSocket(const QByteArray &command) { - int create_socket; - struct sockaddr_un address; + int fd = 0; + struct sockaddr_un address; - if ((create_socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { - perror("Could not create socket"); - return -1; - } + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { + perror("Could not create socket"); + return -1; + } - if (fcntl(create_socket, F_SETFD, FD_CLOEXEC) == -1) { - perror("Unable to set CLOEXEC"); - } + if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) + perror("Unable to set CLOEXEC"); - setupAddressStruct(address); + setupAddressStruct(address); - if (connect(create_socket, (struct sockaddr *) &address, sizeof (address)) != 0) { - perror("Could not connect"); - return -1; - } - close(create_socket); - return 0; + if (connect(fd, (struct sockaddr *) &address, sizeof (address)) != 0) { + perror("Could not connect"); + return -1; + } + + QLocalSocket localSocket; + if (!localSocket.setSocketDescriptor(fd)) { + fprintf(stderr, "Unable to initialize local socket from descriptor.\n"); + close(fd); + return -1; + } + + if (localSocket.write(command) != command.size()) { + fprintf(stderr, "Could not send command"); + return -1; + } + localSocket.waitForBytesWritten(); + return 0; } static int createServerSocket() @@ -122,7 +134,7 @@ static int createServerSocket() return -1; } - if (connectSocket() != 0) { + if (connectSocket("stop") != 0) { fprintf(stderr, "Failed to connect to process\n"); } @@ -143,7 +155,7 @@ static int createServerSocket() static void stop() { - connectSocket(); + connectSocket("stop"); } static int openServer(QTcpServer *s, Utils::PortList &range) diff --git a/process.cpp b/process.cpp index 7842deb..ce699c0 100644 --- a/process.cpp +++ b/process.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -261,8 +262,33 @@ void Process::stop() void Process::incomingConnection(int i) { - accept(i, NULL, NULL); - stop(); + int fd = accept(i, NULL, NULL); + if (fd < 0 ) { + perror("Could not accept connection"); + stop(); + return; + } + + QLocalSocket localSocket; + if (!localSocket.setSocketDescriptor(fd)) { + fprintf(stderr, "Could not initialize local socket from descriptor.\n"); + close(fd); + stop(); + return; + } + + if (!localSocket.waitForReadyRead()) { + fprintf(stderr, "No command received.\n"); + stop(); // default + return; + } + + QByteArray command = localSocket.readAll(); + + if (command == "stop") + stop(); + else + stop(); } void Process::setSocketNotifier(QSocketNotifier *s) From 2631768b484176836694ec4afdb81ef31886c142 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 3 Jun 2015 09:39:13 +0200 Subject: [PATCH 05/27] Add command to restart current application Task-number: QTEE-931 Change-Id: I0ad4246750142289cca2a4cbf853211a60538362 Reviewed-by: Laszlo Agocs --- main.cpp | 18 +++++++++++------- process.cpp | 50 ++++++++++++++++++++++++++++++++++++++------------ process.h | 5 ++++- 3 files changed, 53 insertions(+), 20 deletions(-) diff --git a/main.cpp b/main.cpp index 06bf501..08be98c 100644 --- a/main.cpp +++ b/main.cpp @@ -62,6 +62,7 @@ static void usage() "--print-debug Print debug messages to stdout on Android\n" "--version Print version information\n" "--detach Start application as usual, then go into background\n" + "--restart Restart the current running application\n" "--help, -h, -help Show this help\n" ); } @@ -158,6 +159,11 @@ static void stop() connectSocket("stop"); } +static void restart() +{ + connectSocket("restart"); +} + static int openServer(QTcpServer *s, Utils::PortList &range) { while (range.hasMore()) { @@ -173,7 +179,7 @@ static int findFirstFreePort(Utils::PortList &range) return openServer(&s, range); } -static bool parseConfigFile(Config *config, const QString &fileName) +bool parseConfigFile(Config *config, const QString &fileName) { QFile f(fileName); @@ -211,7 +217,7 @@ static bool parseConfigFile(Config *config, const QString &fileName) return true; } -static bool parseConfigFileDirectory(Config *config, const QString &dirName) +bool parseConfigFileDirectory(Config *config, const QString &dirName) { QDir d(dirName); if (d.exists()) { @@ -227,7 +233,6 @@ static bool parseConfigFileDirectory(Config *config, const QString &dirName) return true; } - static bool removeDefault() { if (QFile::exists(B2QT_PREFIX)) { @@ -309,10 +314,6 @@ int main(int argc, char **argv) if (!parseConfigFile(&config, "/etc/appcontroller.conf")) fprintf(stderr, "Failed to parse config file.\n"); - // Parse temporary config files - parseConfigFileDirectory(&config, "/var/lib/b2qt/appcontroller.conf.d"); - parseConfigFileDirectory(&config, "/tmp/b2qt/appcontroller.conf.d"); - while (!args.isEmpty()) { const QString arg(args.takeFirst()); @@ -371,6 +372,9 @@ int main(int argc, char **argv) return 0; } else if (arg == "--detach") { detach = true; + } else if (arg == "--restart") { + restart(); + return 0; } else if (arg == "--help" || arg == "-help" || arg == "-h") { usage(); return 0; diff --git a/process.cpp b/process.cpp index ce699c0..64bbc13 100644 --- a/process.cpp +++ b/process.cpp @@ -30,6 +30,7 @@ #include #include +bool parseConfigFileDirectory(Config *config, const QString &dirName); static int pipefd[2]; static void signalhandler(int) @@ -90,13 +91,13 @@ Process::Process() , mDebuggee(0) , mDebug(false) , mStdoutFd(1) + , mBeingRestarted(false) { mProcess->setProcessChannelMode(QProcess::SeparateChannels); connect(mProcess, &QProcess::readyReadStandardError, this, &Process::readyReadStandardError); connect(mProcess, &QProcess::readyReadStandardOutput, this, &Process::readyReadStandardOutput); connect(mProcess, (void (QProcess::*)(int, QProcess::ExitStatus))&QProcess::finished, this, &Process::finished); connect(mProcess, (void (QProcess::*)(QProcess::ProcessError))&QProcess::error, this, &Process::error); - connect(mProcess, (void (QProcess::*)(int, QProcess::ExitStatus))&QProcess::finished, qApp, &QCoreApplication::quit); if (pipe2(pipefd, O_CLOEXEC) != 0) qWarning("Could not create pipe"); @@ -195,7 +196,8 @@ void Process::error(QProcess::ProcessError error) printf("Unknown error\n"); break; } - qApp->quit(); + if (!mBeingRestarted) + qApp->quit(); } void Process::finished(int exitCode, QProcess::ExitStatus exitStatus) @@ -204,28 +206,41 @@ void Process::finished(int exitCode, QProcess::ExitStatus exitStatus) printf("Process exited with exit code %d\n", exitCode); else printf("Process stopped\n"); + if (!mBeingRestarted) { + qDebug() << "quit"; + qApp->quit(); + } } -void Process::startup(QStringList args) +void Process::startup() { #ifdef Q_OS_ANDROID QProcessEnvironment pe = interactiveProcessEnvironment(); #else QProcessEnvironment pe = QProcessEnvironment::systemEnvironment(); #endif + QStringList args = mStartupArguments; + mBeingRestarted = false; + + Config actualConfig = mConfig; + + // Parse temporary config files + // This needs to be done on every startup because those files are expected to change. + parseConfigFileDirectory(&actualConfig, "/var/lib/b2qt/appcontroller.conf.d"); + parseConfigFileDirectory(&actualConfig, "/tmp/b2qt/appcontroller.conf.d"); - foreach (const QString &key, mConfig.env.keys()) { + foreach (const QString &key, actualConfig.env.keys()) { if (!pe.contains(key)) { - qDebug() << key << mConfig.env.value(key); - pe.insert(key, mConfig.env.value(key)); + qDebug() << key << actualConfig.env.value(key); + pe.insert(key, actualConfig.env.value(key)); } } - if (!mConfig.base.isEmpty()) - pe.insert(QLatin1String("B2QT_BASE"), mConfig.base); - if (!mConfig.platform.isEmpty()) - pe.insert(QLatin1String("B2QT_PLATFORM"), mConfig.platform); + if (!actualConfig.base.isEmpty()) + pe.insert(QLatin1String("B2QT_BASE"), actualConfig.base); + if (!actualConfig.platform.isEmpty()) + pe.insert(QLatin1String("B2QT_PLATFORM"), actualConfig.platform); - args.append(mConfig.args); + args.append(actualConfig.args); mProcess->setProcessEnvironment(pe); mBinary = args.first(); @@ -236,7 +251,8 @@ void Process::startup(QStringList args) void Process::start(const QStringList &args) { - startup(args); + mStartupArguments = args; + startup(); } void Process::stop() @@ -260,6 +276,14 @@ void Process::stop() mProcess->kill(); } +void Process::restart() +{ + printf("Restarting application\n"); + mBeingRestarted = true; + stop(); + startup(); +} + void Process::incomingConnection(int i) { int fd = accept(i, NULL, NULL); @@ -287,6 +311,8 @@ void Process::incomingConnection(int i) if (command == "stop") stop(); + else if (command == "restart") + restart(); else stop(); } diff --git a/process.h b/process.h index d175dd3..105d051 100644 --- a/process.h +++ b/process.h @@ -60,6 +60,7 @@ class Process : public QObject void setStdoutFd(qintptr stdoutFd); public slots: void stop(); + void restart(); private slots: void readyReadStandardError(); void readyReadStandardOutput(); @@ -68,7 +69,7 @@ private slots: void incomingConnection(int); private: void forwardProcessOutput(qintptr fd, const QByteArray &data); - void startup(QStringList); + void startup(); QProcessEnvironment interactiveProcessEnvironment() const; QProcess *mProcess; int mDebuggee; @@ -76,6 +77,8 @@ private slots: Config mConfig; QString mBinary; qintptr mStdoutFd; + QStringList mStartupArguments; + bool mBeingRestarted; }; #endif // PROCESS_H From 3804f0dc00471a209bb5d85ba3816c09af877109 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Tue, 9 Jun 2015 12:34:12 +0200 Subject: [PATCH 06/27] Make appcontroller a temporary daemon For a restart being successful the application has to be shut down with out terminating the appcontroller. Afterwards the appcontroller will be able to start the application again. Change-Id: I38fd0aded176a10dac40c419b6866ce70ec1fcef Reviewed-by: Laszlo Agocs --- main.cpp | 11 ++++++++++- process.cpp | 12 +++++++++++- process.h | 1 + 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/main.cpp b/main.cpp index 08be98c..63341fe 100644 --- a/main.cpp +++ b/main.cpp @@ -55,6 +55,7 @@ static void usage() "--debug-gdb Start GDB debugging\n" "--debug-qml Start QML debugging\n" "--stop Stop already running application\n" + "--stop-for-restart Stop already running application and prepare to restart it\n" "--launch Start application without stopping already running application\n" "--show-platform Show platform information\n" "--make-default Make this application the default on boot\n" @@ -62,7 +63,7 @@ static void usage() "--print-debug Print debug messages to stdout on Android\n" "--version Print version information\n" "--detach Start application as usual, then go into background\n" - "--restart Restart the current running application\n" + "--restart Restart the current running application or an application stopped with --stop-for-restart\n" "--help, -h, -help Show this help\n" ); } @@ -164,6 +165,11 @@ static void restart() connectSocket("restart"); } +static void stopForRestart() +{ + connectSocket("stopForRestart"); +} + static int openServer(QTcpServer *s, Utils::PortList &range) { while (range.hasMore()) { @@ -375,6 +381,9 @@ int main(int argc, char **argv) } else if (arg == "--restart") { restart(); return 0; + } else if (arg == "--stop-for-restart") { + stopForRestart(); + return 0; } else if (arg == "--help" || arg == "-help" || arg == "-h") { usage(); return 0; diff --git a/process.cpp b/process.cpp index 64bbc13..d3d8fdb 100644 --- a/process.cpp +++ b/process.cpp @@ -259,7 +259,8 @@ void Process::stop() { if (mProcess->state() == QProcess::QProcess::NotRunning) { printf("No process running\n"); - qApp->exit(); + if (!mBeingRestarted) + qApp->exit(); return; } @@ -276,6 +277,13 @@ void Process::stop() mProcess->kill(); } +void Process::stopForRestart() +{ + printf("Stopping application for restart\n"); + mBeingRestarted = true; + stop(); +} + void Process::restart() { printf("Restarting application\n"); @@ -313,6 +321,8 @@ void Process::incomingConnection(int i) stop(); else if (command == "restart") restart(); + else if (command == "stopForRestart") + stopForRestart(); else stop(); } diff --git a/process.h b/process.h index 105d051..10fc13b 100644 --- a/process.h +++ b/process.h @@ -60,6 +60,7 @@ class Process : public QObject void setStdoutFd(qintptr stdoutFd); public slots: void stop(); + void stopForRestart(); void restart(); private slots: void readyReadStandardError(); From 45d549fe274cd8f16578b2ff9a34af40fd9b98a9 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Fri, 12 Jun 2015 09:51:57 +0200 Subject: [PATCH 07/27] Add feature info Change-Id: Ibc85618c0de0478a2fb2de45f19e2dc654109635 Reviewed-by: Laszlo Agocs --- main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 63341fe..f4c2233 100644 --- a/main.cpp +++ b/main.cpp @@ -36,6 +36,7 @@ #include #define PID_FILE "/data/user/.appcontroller" +#define FEATURES "perf eglresize" #ifdef Q_OS_ANDROID #define B2QT_PREFIX "/data/user/b2qt" @@ -374,7 +375,7 @@ int main(int argc, char **argv) } else if (arg == "--print-debug") { config.flags |= Config::PrintDebugMessages; } else if (arg == "--version") { - printf("Appcontroller version: " GIT_VERSION "\nGit revision: " GIT_HASH "\n"); + printf("Appcontroller version: " GIT_VERSION "\nGit revision: " GIT_HASH "\nFeatures: " FEATURES "\n"); return 0; } else if (arg == "--detach") { detach = true; From 7ac47bee4c6bd55df8c0cad14ff11457fbf07158 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Mon, 15 Jun 2015 10:41:30 +0200 Subject: [PATCH 08/27] Add restart to feature string Change-Id: Iee8d8a1eda473dbc4a4ec4efb3baf9cc2eb18a5a Reviewed-by: Laszlo Agocs --- main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index f4c2233..3442954 100644 --- a/main.cpp +++ b/main.cpp @@ -36,7 +36,7 @@ #include #define PID_FILE "/data/user/.appcontroller" -#define FEATURES "perf eglresize" +#define FEATURES "restart perf eglresize" #ifdef Q_OS_ANDROID #define B2QT_PREFIX "/data/user/b2qt" From 26b255dd1a53a8f276c0e33bda896945600b404d Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 14 Aug 2015 11:16:06 +0200 Subject: [PATCH 09/27] Add --qml-debug-services argument We don't want to load the QML debugger and inspector services when profiling as the V4 debugger forces the QML engine into interpreter mode. By specifying the services we need we can avoid this. Change-Id: I8ec126155c43848f26d536a56c3a1da067864401 Reviewed-by: Rainer Keller --- main.cpp | 50 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/main.cpp b/main.cpp index 3442954..17862ad 100644 --- a/main.cpp +++ b/main.cpp @@ -36,7 +36,7 @@ #include #define PID_FILE "/data/user/.appcontroller" -#define FEATURES "restart perf eglresize" +#define FEATURES "restart perf eglresize qmldebugservices" #ifdef Q_OS_ANDROID #define B2QT_PREFIX "/data/user/b2qt" @@ -50,22 +50,28 @@ static const char socketPath[] = "#Boot2Qt_appcontroller"; static void usage() { - printf("appcontroller [--debug-gdb] [--debug-qml] [--port-range ] [--stop] [--launch] [--show-platfrom] [--make-default] [--remove-default] [--print-debug] [--version] [--detach] [executable] [arguments]\n" + printf("appcontroller [--debug-gdb] [--debug-qml] [--qml-debug-services ]" + " [--port-range ] [--stop] [--launch] [--show-platfrom] [--make-default]" + " [--remove-default] [--print-debug] [--version] [--detach] [executable] [arguments]\n" "\n" - "--port-range Port range to use for debugging connections\n" - "--debug-gdb Start GDB debugging\n" - "--debug-qml Start QML debugging\n" - "--stop Stop already running application\n" - "--stop-for-restart Stop already running application and prepare to restart it\n" - "--launch Start application without stopping already running application\n" - "--show-platform Show platform information\n" - "--make-default Make this application the default on boot\n" - "--remove-default Restore the default application\n" - "--print-debug Print debug messages to stdout on Android\n" - "--version Print version information\n" - "--detach Start application as usual, then go into background\n" - "--restart Restart the current running application or an application stopped with --stop-for-restart\n" - "--help, -h, -help Show this help\n" + "--port-range Port range to use for debugging connections\n" + "--debug-gdb Start GDB debugging\n" + "--debug-qml Start QML debugging or profiling\n" + "--qml-debug-services Specify services to use for QML debugging/profiling\n" + "--stop Stop already running application\n" + "--stop-for-restart Stop already running application and prepare to\n" + " restart it\n" + "--launch Start application without stopping already running\n" + " application\n" + "--show-platform Show platform information\n" + "--make-default Make this application the default on boot\n" + "--remove-default Restore the default application\n" + "--print-debug Print debug messages to stdout on Android\n" + "--version Print version information\n" + "--detach Start application as usual, then go into background\n" + "--restart Restart the current running application or an\n" + " application stopped with --stop-for-restart\n" + "--help, -h, -help Show this help\n" ); } @@ -307,6 +313,7 @@ int main(int argc, char **argv) quint16 gdbDebugPort = 0; bool useGDB = false; bool useQML = false; + QString qmlDebugServices; QStringList perfParams; bool fireAndForget = false; bool detach = false; @@ -340,6 +347,13 @@ int main(int argc, char **argv) setsid(); } else if (arg == "--debug-qml") { useQML = true; + } else if (arg == "--qml-debug-services") { + if (args.isEmpty()) { + fprintf(stderr, "--qml-debug-services requires a list of comma-separated service " + "names.\n"); + return 1; + } + qmlDebugServices = args.takeFirst(); } else if (arg == "--profile-perf") { if (args.isEmpty()) { fprintf(stderr, "--profile-perf requires comma-separated list of parameters that " @@ -423,7 +437,9 @@ int main(int argc, char **argv) fprintf(stderr, "Could not find an unused port in range\n"); return 1; } - defaultArgs.push_front("-qmljsdebugger=port:" + QString::number(port) + ",block"); + defaultArgs.push_front("-qmljsdebugger=port:" + QString::number(port) + ",block" + + (qmlDebugServices.isEmpty() ? + "" : (",services:" + qmlDebugServices))); printf("QML Debugger: Going to wait for connection on port %d...\n", port); } From 6b5ef93020d471fe21152e2428e2f0c5bc7dc24d Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 3 Jun 2015 10:55:29 +0200 Subject: [PATCH 10/27] Remove Android code Change-Id: I8a69405655483c6bbd9f402df4a06a1020b6bebe Reviewed-by: aavit --- main.cpp | 9 +------ process.cpp | 74 ----------------------------------------------------- process.h | 9 +------ 3 files changed, 2 insertions(+), 90 deletions(-) diff --git a/main.cpp b/main.cpp index 17862ad..a1188f0 100644 --- a/main.cpp +++ b/main.cpp @@ -38,11 +38,7 @@ #define PID_FILE "/data/user/.appcontroller" #define FEATURES "restart perf eglresize qmldebugservices" -#ifdef Q_OS_ANDROID - #define B2QT_PREFIX "/data/user/b2qt" -#else - #define B2QT_PREFIX "/usr/bin/b2qt" -#endif +#define B2QT_PREFIX "/usr/bin/b2qt" static int serverSocket = -1; @@ -66,7 +62,6 @@ static void usage() "--show-platform Show platform information\n" "--make-default Make this application the default on boot\n" "--remove-default Restore the default application\n" - "--print-debug Print debug messages to stdout on Android\n" "--version Print version information\n" "--detach Start application as usual, then go into background\n" "--restart Restart the current running application or an\n" @@ -386,8 +381,6 @@ int main(int argc, char **argv) return 0; else return 1; - } else if (arg == "--print-debug") { - config.flags |= Config::PrintDebugMessages; } else if (arg == "--version") { printf("Appcontroller version: " GIT_VERSION "\nGit revision: " GIT_HASH "\nFeatures: " FEATURES "\n"); return 0; diff --git a/process.cpp b/process.cpp index d3d8fdb..2ee9246 100644 --- a/process.cpp +++ b/process.cpp @@ -144,12 +144,8 @@ void Process::forwardProcessOutput(qintptr fd, const QByteArray &data) size -= written; constData += written; } - - if (mConfig.flags.testFlag(Config::PrintDebugMessages)) - qDebug() << data; } - void Process::readyReadStandardOutput() { forwardProcessOutput(mStdoutFd, mProcess->readAllStandardOutput()); @@ -214,11 +210,7 @@ void Process::finished(int exitCode, QProcess::ExitStatus exitStatus) void Process::startup() { -#ifdef Q_OS_ANDROID - QProcessEnvironment pe = interactiveProcessEnvironment(); -#else QProcessEnvironment pe = QProcessEnvironment::systemEnvironment(); -#endif QStringList args = mStartupArguments; mBeingRestarted = false; @@ -341,69 +333,3 @@ void Process::setStdoutFd(qintptr stdoutFd) { mStdoutFd = stdoutFd; } - -QProcessEnvironment Process::interactiveProcessEnvironment() const -{ - QProcessEnvironment env; - - QProcess process; - process.start("sh"); - if (!process.waitForStarted(3000)) { - printf("Could not start shell.\n"); - return env; - } - - process.write("source /system/etc/mkshrc\n"); - process.write("export -p\n"); - process.closeWriteChannel(); - - printf("waiting for process to finish\n"); - if (!process.waitForFinished(1000)) { - printf("did not finish: terminate\n"); - process.terminate(); - if (!process.waitForFinished(1000)) { - printf("did not terminate: kill\n"); - process.kill(); - if (!process.waitForFinished(1000)) { - printf("Could not stop process.\n"); - } - } - } - - QList list = process.readAllStandardOutput().split('\n'); - if (list.isEmpty()) - printf("Failed to read environment output\n"); - - foreach (QByteArray entry, list) { - if (entry.startsWith("export ")) { - entry = entry.mid(7); - } else if (entry.startsWith("declare -x ")) { - entry = entry.mid(11); - } else { - continue; - } - - QByteArray key; - QByteArray value; - int index = entry.indexOf('='); - - if (index > 0) { - key = entry.left(index); - value = entry.mid(index + 1); - } else { - key = entry; - // value is empty - } - - // Remove simple escaping. - // This is not complete. - if (value.startsWith('\'') and value.endsWith('\'')) - value = value.mid(1, value.size()-2); - else if (value.startsWith('"') and value.endsWith('"')) - value = value.mid(1, value.size()-2); - - env.insert(key, value); - } - - return env; -} diff --git a/process.h b/process.h index 10fc13b..46bea62 100644 --- a/process.h +++ b/process.h @@ -27,23 +27,17 @@ class QSocketNotifier; struct Config { - enum Flag { - PrintDebugMessages = 0x01 - }; - Q_DECLARE_FLAGS(Flags, Flag) - enum DebugInterface{ LocalDebugInterface, PublicDebugInterface }; - Config() : platform("unknown"), flags(0), debugInterface(LocalDebugInterface) { } + Config() : platform("unknown"), debugInterface(LocalDebugInterface) { } QString base; QString platform; QMap env; QStringList args; - Flags flags; DebugInterface debugInterface; }; @@ -71,7 +65,6 @@ private slots: private: void forwardProcessOutput(qintptr fd, const QByteArray &data); void startup(); - QProcessEnvironment interactiveProcessEnvironment() const; QProcess *mProcess; int mDebuggee; bool mDebug; From af3ab8ec0213a40d90f3d58a8a65a944b0cd753e Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 14 Aug 2015 11:18:40 +0200 Subject: [PATCH 11/27] Add note about --profile-perf to usage message Change-Id: I50163b3c5f085f12f102fb0eb455eaf6ebda6ffa Reviewed-by: Rainer Keller --- main.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/main.cpp b/main.cpp index a1188f0..7b8b7be 100644 --- a/main.cpp +++ b/main.cpp @@ -47,13 +47,15 @@ static const char socketPath[] = "#Boot2Qt_appcontroller"; static void usage() { printf("appcontroller [--debug-gdb] [--debug-qml] [--qml-debug-services ]" - " [--port-range ] [--stop] [--launch] [--show-platfrom] [--make-default]" - " [--remove-default] [--print-debug] [--version] [--detach] [executable] [arguments]\n" + " [--profile-perf ] [--port-range ] [--stop] [--launch] [--show-platfrom]" + " [--make-default] [--remove-default] [--print-debug] [--version] [--detach]" + " [executable] [arguments]\n" "\n" "--port-range Port range to use for debugging connections\n" "--debug-gdb Start GDB debugging\n" "--debug-qml Start QML debugging or profiling\n" "--qml-debug-services Specify services to use for QML debugging/profiling\n" + "--profile-perf Start perf profiling\n" "--stop Stop already running application\n" "--stop-for-restart Stop already running application and prepare to\n" " restart it\n" @@ -351,10 +353,10 @@ int main(int argc, char **argv) qmlDebugServices = args.takeFirst(); } else if (arg == "--profile-perf") { if (args.isEmpty()) { - fprintf(stderr, "--profile-perf requires comma-separated list of parameters that " - "get passed to \"perf record\". Arguments \"-o -\" are " - "automatically appended to capture the output as stream. " - "Escape commas by doubling them."); + fprintf(stderr, "--profile-perf requires comma-separated list of parameters that\n" + "get passed to \"perf record\". Arguments \"-o -\" are\n" + "automatically appended to capture the output as stream.\n" + "Escape commas by doubling them.\n"); return 1; } perfParams = extractPerfParams(args.takeFirst()); From 77a798298ffc8db5ecf6e40e8b371426fa025dcb Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 29 Feb 2016 16:48:00 +0100 Subject: [PATCH 12/27] Don't join application arguments when running in perf mode ... otherwise we get "command not found". Change-Id: I9f471d8b7021df83f0c09c3f06addb977f17353c Task-number: QCE-67 Reviewed-by: Rainer Keller --- main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 7b8b7be..854276e 100644 --- a/main.cpp +++ b/main.cpp @@ -501,7 +501,7 @@ int main(int argc, char **argv) QStringList allArgs; allArgs << QLatin1String("perf") << QLatin1String("record") << perfParams << QLatin1String("-o") << QLatin1String("-") - << QLatin1String("--") << defaultArgs.join(QLatin1Char(' ')); + << QLatin1String("--") << defaultArgs; PerfProcessHandler *server = new PerfProcessHandler(&process, allArgs); int port = openServer(server->server(), range); From 1e3c96e0e4f28a072c835775f7fdc310eb3b4f28 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 9 Mar 2016 14:59:48 +0100 Subject: [PATCH 13/27] Do not kill the process group When restarting an application the process seems to kill itself. Task-number: QTEE-1085 Change-Id: I88598fe4bd6ed5423c1412036eaf1ea1572bc889 Reviewed-by: David Schulz Reviewed-by: Ulf Hermann --- process.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/process.cpp b/process.cpp index 2ee9246..451e1f8 100644 --- a/process.cpp +++ b/process.cpp @@ -261,8 +261,6 @@ void Process::stop() if (kill(mDebuggee, SIGKILL) != 0) perror("Could not kill debugee"); } - if (kill(-getpid(), SIGTERM) != 0) - perror("Could not kill process group"); mProcess->terminate(); if (!mProcess->waitForFinished()) From 271cf667d74a91acf3c203180526ac449ba0c49a Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Tue, 18 Oct 2016 10:03:04 +0200 Subject: [PATCH 14/27] Fix setting default application with invalid symlink Change-Id: Ia99140c0a8f8cf201eeaad352c36becbb1f6636f Reviewed-by: Karim Pinter Reviewed-by: Samuli Piippo --- main.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/main.cpp b/main.cpp index 854276e..db818e6 100644 --- a/main.cpp +++ b/main.cpp @@ -245,14 +245,32 @@ bool parseConfigFileDirectory(Config *config, const QString &dirName) static bool removeDefault() { - if (QFile::exists(B2QT_PREFIX)) { + QFileInfo fi(B2QT_PREFIX); + + if (fi.isSymLink()) { if (!QFile::remove(B2QT_PREFIX)) { fprintf(stderr, "Could not remove default application.\n"); return false; } sync(); + return true; } - return true; + + if (fi.isDir()) { + fprintf(stderr, "Could not remove default application because '" B2QT_PREFIX "' is a directory. It should be a symlink.\n"); + return false; + } + + if (fi.isFile()) { + fprintf(stderr, "Could not remove default application because '" B2QT_PREFIX "' is a file. It should be a symlink.\n"); + return false; + } + + if (!fi.exists()) { + return true; + } + + return false; } static bool makeDefault(const QString &filepath) From 384775293c03db5d25b57f112eaa1a01e380cbe6 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 23 Nov 2016 13:15:28 +0100 Subject: [PATCH 15/27] Change license text Change-Id: I74e5115a032cd94d245e63d7d9e47f3d028e0110 Reviewed-by: Samuli Piippo --- main.cpp | 25 ++++++++++++++----------- perfprocesshandler.cpp | 25 ++++++++++++++----------- perfprocesshandler.h | 25 ++++++++++++++----------- portlist.cpp | 25 ++++++++++++++----------- portlist.h | 25 ++++++++++++++----------- process.cpp | 25 ++++++++++++++----------- process.h | 25 ++++++++++++++----------- 7 files changed, 98 insertions(+), 77 deletions(-) diff --git a/main.cpp b/main.cpp index 854276e..13bd85e 100644 --- a/main.cpp +++ b/main.cpp @@ -1,20 +1,23 @@ -/**************************************************************************** +/****************************************************************************** ** -** Copyright (C) 2014 Digia Plc -** All rights reserved. -** For any questions to Digia, please use contact form at http://www.qt.io +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** -** This file is part of Qt Enterprise Embedded. +** This file is part of Qt for Device Creation. ** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** 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. +** 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. ** -** If you have questions regarding the use of this file, please use -** contact form at http://www.qt.io +** $QT_END_LICENSE$ ** -****************************************************************************/ +******************************************************************************/ #include "process.h" #include "portlist.h" diff --git a/perfprocesshandler.cpp b/perfprocesshandler.cpp index 9b609ab..2f6000b 100644 --- a/perfprocesshandler.cpp +++ b/perfprocesshandler.cpp @@ -1,20 +1,23 @@ -/**************************************************************************** +/****************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd -** All rights reserved. -** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** -** This file is part of QtEnterprise Embedded. +** This file is part of Qt for Device Creation. ** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** 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 The Qt Company. +** 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. ** -** If you have questions regarding the use of this file, please use -** contact form at http://www.qt.io/contact-us +** $QT_END_LICENSE$ ** -****************************************************************************/ +******************************************************************************/ #include "perfprocesshandler.h" #include diff --git a/perfprocesshandler.h b/perfprocesshandler.h index f10e8a6..b7867ce 100644 --- a/perfprocesshandler.h +++ b/perfprocesshandler.h @@ -1,20 +1,23 @@ -/**************************************************************************** +/****************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd -** All rights reserved. -** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** -** This file is part of QtEnterprise Embedded. +** This file is part of Qt for Device Creation. ** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** 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 The Qt Company. +** 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. ** -** If you have questions regarding the use of this file, please use -** contact form at http://www.qt.io/contact-us +** $QT_END_LICENSE$ ** -****************************************************************************/ +******************************************************************************/ #ifndef PERFPROCESSHANDLER_H #define PERFPROCESSHANDLER_H diff --git a/portlist.cpp b/portlist.cpp index a93814e..6a3a0de 100644 --- a/portlist.cpp +++ b/portlist.cpp @@ -1,20 +1,23 @@ -/**************************************************************************** +/****************************************************************************** ** -** Copyright (C) 2014 Digia Plc -** All rights reserved. -** For any questions to Digia, please use contact form at http://www.qt.io +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** -** This file is part of Qt Enterprise Embedded. +** This file is part of Qt for Device Creation. ** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** 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. +** 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. ** -** If you have questions regarding the use of this file, please use -** contact form at http://www.qt.io +** $QT_END_LICENSE$ ** -****************************************************************************/ +******************************************************************************/ #include "portlist.h" diff --git a/portlist.h b/portlist.h index 171194c..5ad0954 100644 --- a/portlist.h +++ b/portlist.h @@ -1,20 +1,23 @@ -/**************************************************************************** +/****************************************************************************** ** -** Copyright (C) 2014 Digia Plc -** All rights reserved. -** For any questions to Digia, please use contact form at http://www.qt.io +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** -** This file is part of Qt Enterprise Embedded. +** This file is part of Qt for Device Creation. ** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** 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. +** 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. ** -** If you have questions regarding the use of this file, please use -** contact form at http://www.qt.io +** $QT_END_LICENSE$ ** -****************************************************************************/ +******************************************************************************/ #ifndef PORTLIST_H #define PORTLIST_H diff --git a/process.cpp b/process.cpp index 451e1f8..954cc12 100644 --- a/process.cpp +++ b/process.cpp @@ -1,20 +1,23 @@ -/**************************************************************************** +/****************************************************************************** ** -** Copyright (C) 2014 Digia Plc -** All rights reserved. -** For any questions to Digia, please use contact form at http://www.qt.io +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** -** This file is part of Qt Enterprise Embedded. +** This file is part of Qt for Device Creation. ** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** 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. +** 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. ** -** If you have questions regarding the use of this file, please use -** contact form at http://www.qt.io +** $QT_END_LICENSE$ ** -****************************************************************************/ +******************************************************************************/ #include "process.h" #include diff --git a/process.h b/process.h index 46bea62..d820707 100644 --- a/process.h +++ b/process.h @@ -1,20 +1,23 @@ -/**************************************************************************** +/****************************************************************************** ** -** Copyright (C) 2014 Digia Plc -** All rights reserved. -** For any questions to Digia, please use contact form at http://www.qt.io +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** -** This file is part of Qt Enterprise Embedded. +** This file is part of Qt for Device Creation. ** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** 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. +** 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. ** -** If you have questions regarding the use of this file, please use -** contact form at http://www.qt.io +** $QT_END_LICENSE$ ** -****************************************************************************/ +******************************************************************************/ #ifndef PROCESS_H #define PROCESS_H From d58e21abe213b727d56b5ab869def70204ff01ec Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 23 Aug 2017 10:33:10 +0200 Subject: [PATCH 16/27] Fix error message Message does not match the parameter names. Change-Id: Ie9d3c52487f596dc43c7b36e4a5bc3ee5fbdaa47 Reviewed-by: hjk --- main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index c1d5391..ef1626f 100644 --- a/main.cpp +++ b/main.cpp @@ -435,7 +435,7 @@ int main(int argc, char **argv) } if (detach && (useGDB || useQML)) { - fprintf(stderr, "Detached debugging not possible. --detach and one of --useGDB, --useQML must not be used together.\n"); + fprintf(stderr, "Detached debugging not possible. --detach and one of --debug-gdb, --debug-qml must not be used together.\n"); return 1; } From 5ab7fdbf0845c40418272bafa565295511055d3b Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 23 Aug 2017 10:35:56 +0200 Subject: [PATCH 17/27] Allow to set used debugging port via commandline Change-Id: I6f99e2bf77aed2503119959d46c48e359940600a Reviewed-by: hjk Reviewed-by: Mikko Gronoff Reviewed-by: Samuli Piippo --- main.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/main.cpp b/main.cpp index ef1626f..421aae1 100644 --- a/main.cpp +++ b/main.cpp @@ -39,7 +39,7 @@ #include #define PID_FILE "/data/user/.appcontroller" -#define FEATURES "restart perf eglresize qmldebugservices" +#define FEATURES "restart perf eglresize qmldebugservices explicitdebugports" #define B2QT_PREFIX "/usr/bin/b2qt" @@ -49,14 +49,17 @@ static const char socketPath[] = "#Boot2Qt_appcontroller"; static void usage() { - printf("appcontroller [--debug-gdb] [--debug-qml] [--qml-debug-services ]" + printf("appcontroller [--debug-gdb] [--debug-gdb-port ]" + " [--debug-qml] [--debug-qml-port ] [--qml-debug-services ]" " [--profile-perf ] [--port-range ] [--stop] [--launch] [--show-platfrom]" " [--make-default] [--remove-default] [--print-debug] [--version] [--detach]" " [executable] [arguments]\n" "\n" "--port-range Port range to use for debugging connections\n" "--debug-gdb Start GDB debugging\n" + "--debug-gdb-port Port to be used for GDB debugging\n" "--debug-qml Start QML debugging or profiling\n" + "--debug-qml-port Port to be used for QML debugging\n" "--qml-debug-services Specify services to use for QML debugging/profiling\n" "--profile-perf Start perf profiling\n" "--stop Stop already running application\n" @@ -329,6 +332,7 @@ int main(int argc, char **argv) QStringList defaultArgs; quint16 gdbDebugPort = 0; + quint16 qmlDebugPort = 0; bool useGDB = false; bool useQML = false; QString qmlDebugServices; @@ -363,8 +367,28 @@ int main(int argc, char **argv) useGDB = true; setpgid(0,0); // must be called before setsid() setsid(); + } else if (arg == "--debug-gdb-port") { + if (args.isEmpty()) { + fprintf(stderr, "--debug-gdb-port requires a port number\n"); + return 1; + } + gdbDebugPort = args.takeFirst().toUInt(); + if (gdbDebugPort < 1) { + fprintf(stderr, "--debug-gdb-port has invalid port number\n"); + return 1; + } } else if (arg == "--debug-qml") { useQML = true; + } else if (arg == "--debug-qml-port") { + if (args.isEmpty()) { + fprintf(stderr, "--debug-qml-port requires a port number\n"); + return 1; + } + qmlDebugPort = args.takeFirst().toUInt(); + if (qmlDebugPort < 1) { + fprintf(stderr, "--debug-qml-port has invalid port number\n"); + return 1; + } } else if (arg == "--qml-debug-services") { if (args.isEmpty()) { fprintf(stderr, "--qml-debug-services requires a list of comma-separated service " @@ -429,8 +453,13 @@ int main(int argc, char **argv) return 1; } - if ((useGDB || useQML) && !range.hasMore()) { - fprintf(stderr, "--port-range is mandatory\n"); + if (useGDB && !(gdbDebugPort || range.hasMore())) { + fprintf(stderr, "--debug-gdb requires --port-range or --debug-gdb-port\n"); + return 1; + } + + if (useQML && !(qmlDebugPort || range.hasMore())) { + fprintf(stderr, "--debug-qml requires --port-range or --debug-qml-port\n"); return 1; } @@ -439,7 +468,10 @@ int main(int argc, char **argv) return 1; } - if (useGDB) { + if (gdbDebugPort && !useGDB) + gdbDebugPort = 0; + + if (useGDB && !gdbDebugPort) { int port = findFirstFreePort(range); if (port < 0) { fprintf(stderr, "Could not find an unused port in range\n"); @@ -448,15 +480,18 @@ int main(int argc, char **argv) gdbDebugPort = port; } if (useQML) { - int port = findFirstFreePort(range); - if (port < 0) { - fprintf(stderr, "Could not find an unused port in range\n"); - return 1; + if (!qmlDebugPort) { + int port = findFirstFreePort(range); + if (port < 0) { + fprintf(stderr, "Could not find an unused port in range\n"); + return 1; + } + qmlDebugPort = port; } - defaultArgs.push_front("-qmljsdebugger=port:" + QString::number(port) + ",block" + + defaultArgs.push_front("-qmljsdebugger=port:" + QString::number(qmlDebugPort) + ",block" + (qmlDebugServices.isEmpty() ? "" : (",services:" + qmlDebugServices))); - printf("QML Debugger: Going to wait for connection on port %d...\n", port); + printf("QML Debugger: Going to wait for connection on port %d...\n", qmlDebugPort); } defaultArgs.push_front(args.takeFirst()); From 474fa4b7aee62e704158d213d9e67eba74c69401 Mon Sep 17 00:00:00 2001 From: Samuli Piippo Date: Tue, 27 Aug 2019 10:07:44 +0300 Subject: [PATCH 18/27] Add option to read environment variables from a file Add option "environmentFile=..." that can be point to a separate file containing environment variables in ENV=VALUE pairs, which is normally used in /etc/default/ config files. Change-Id: If21d6c260d93f1ada309eb4e917b30e9c2daa877 Reviewed-by: Kari Oikarinen --- main.cpp | 23 +++++++++++++++++++++++ process.h | 1 + 2 files changed, 24 insertions(+) diff --git a/main.cpp b/main.cpp index 421aae1..8f6d214 100644 --- a/main.cpp +++ b/main.cpp @@ -195,6 +195,25 @@ static int findFirstFreePort(Utils::PortList &range) return openServer(&s, range); } +bool readEnvs(Config *config) +{ + QFile f(config->envFile); + if (!f.open(QFile::ReadOnly)) { + fprintf(stderr, "Could not read environment file: %s\n", qPrintable(config->envFile)); + return false; + } + + while (!f.atEnd()) { + const auto line = f.readLine().simplified(); + if (!line.startsWith("#")) { + const auto index = line.indexOf('='); + config->env[line.left(index)] = line.mid(index + 1); + } + } + f.close(); + return true; +} + bool parseConfigFile(Config *config, const QString &fileName) { QFile f(fileName); @@ -227,6 +246,8 @@ bool parseConfigFile(Config *config, const QString &fileName) config->debugInterface = Config::PublicDebugInterface; else qWarning() << "Unkonwn value for debuginterface:" << value; + } else if (line.startsWith("environmentFile=")) { + config->envFile = line.mid(16).simplified(); } } f.close(); @@ -349,6 +370,8 @@ int main(int argc, char **argv) Config config; if (!parseConfigFile(&config, "/etc/appcontroller.conf")) fprintf(stderr, "Failed to parse config file.\n"); + if (!config.envFile.isEmpty()) + readEnvs(&config); while (!args.isEmpty()) { const QString arg(args.takeFirst()); diff --git a/process.h b/process.h index d820707..8b84779 100644 --- a/process.h +++ b/process.h @@ -42,6 +42,7 @@ struct Config { QMap env; QStringList args; DebugInterface debugInterface; + QString envFile; }; class Process : public QObject From d9978f10a0ef60563fdff8f8eadcb5a678b9a5b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pasi=20Pet=C3=A4j=C3=A4j=C3=A4rvi?= Date: Fri, 20 Aug 2021 14:48:26 +0300 Subject: [PATCH 19/27] Add cmake support Task-number: QTBUG-86119 Change-Id: I858cdcc75e8b26007c244f9ef4efebb5da9cd66a Reviewed-by: Samuli Piippo --- .cmake.conf | 1 + CMakeLists.txt | 26 ++++++++++++++++++++++++++ appcontroller.pro | 40 ---------------------------------------- main.cpp | 2 +- 4 files changed, 28 insertions(+), 41 deletions(-) create mode 100644 .cmake.conf create mode 100644 CMakeLists.txt delete mode 100644 appcontroller.pro diff --git a/.cmake.conf b/.cmake.conf new file mode 100644 index 0000000..16ecb3d --- /dev/null +++ b/.cmake.conf @@ -0,0 +1 @@ +add_compile_definitions(APPCONTROLLER_VERSION="1.0.0") diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7c96b7c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.16) +include(.cmake.conf) + +project(appcontroller LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) + +find_package(Qt6 COMPONENTS Network) + +qt6_add_executable(appcontroller + main.cpp + process.cpp + portlist.cpp + perfprocesshandler.cpp +) + +target_link_libraries(appcontroller PUBLIC + Qt::Network +) + +install(TARGETS appcontroller + RUNTIME DESTINATION bin +) diff --git a/appcontroller.pro b/appcontroller.pro deleted file mode 100644 index 97b208e..0000000 --- a/appcontroller.pro +++ /dev/null @@ -1,40 +0,0 @@ -QT-=gui -QT+=network -HEADERS=\ - process.h \ - portlist.h \ - perfprocesshandler.h - -SOURCES=\ - main.cpp \ - process.cpp \ - portlist.cpp \ - perfprocesshandler.cpp - -android { - target.path = $$[INSTALL_ROOT]/system/bin -} else { - target.path = $$[INSTALL_ROOT]/usr/bin -} -INSTALLS+=target - -# Find out git hash -exists(.git) { - unix:system(which git):HAS_GIT=TRUE - win32:system(where git.exe):HAS_GIT=TRUE - contains(HAS_GIT, TRUE) { - GIT_HASH=$$system(git log -1 --format=%H) - !system(git diff-index --quiet HEAD): GIT_HASH="$$GIT_HASH-dirty" - GIT_VERSION=$$system(git describe --tags --exact-match) - isEmpty(GIT_VERSION) : GIT_VERSION="unknown" - } -} else { - GIT_HASH="unknown" - GIT_VERSION="unknown" -} - -isEmpty(GIT_VERSION) : error("No suitable tag found") -isEmpty(GIT_HASH) : error("No hash available") - -DEFINES+="GIT_HASH=\\\"$$GIT_HASH\\\"" -DEFINES+="GIT_VERSION=\\\"$$GIT_VERSION\\\"" diff --git a/main.cpp b/main.cpp index 8f6d214..213339a 100644 --- a/main.cpp +++ b/main.cpp @@ -452,7 +452,7 @@ int main(int argc, char **argv) else return 1; } else if (arg == "--version") { - printf("Appcontroller version: " GIT_VERSION "\nGit revision: " GIT_HASH "\nFeatures: " FEATURES "\n"); + printf("Appcontroller version: " APPCONTROLLER_VERSION "\nFeatures: " FEATURES "\n"); return 0; } else if (arg == "--detach") { detach = true; From 3e0ecc85628f17e4d7929f3341aa76b376b8080e Mon Sep 17 00:00:00 2001 From: Ari Parkkila Date: Mon, 3 Oct 2022 07:58:50 +0300 Subject: [PATCH 20/27] Change obsoleted QProcess::error to errorOccurred Fixes: QTBUG-106664 Pick-to: 5.15 Change-Id: Iee18315915b7317b76e4d241c7f8ad439d8260fa Reviewed-by: Samuli Piippo --- process.cpp | 4 ++-- process.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/process.cpp b/process.cpp index 954cc12..4df8270 100644 --- a/process.cpp +++ b/process.cpp @@ -100,7 +100,7 @@ Process::Process() connect(mProcess, &QProcess::readyReadStandardError, this, &Process::readyReadStandardError); connect(mProcess, &QProcess::readyReadStandardOutput, this, &Process::readyReadStandardOutput); connect(mProcess, (void (QProcess::*)(int, QProcess::ExitStatus))&QProcess::finished, this, &Process::finished); - connect(mProcess, (void (QProcess::*)(QProcess::ProcessError))&QProcess::error, this, &Process::error); + connect(mProcess, (void (QProcess::*)(QProcess::ProcessError))&QProcess::errorOccurred, this, &Process::errorOccurred); if (pipe2(pipefd, O_CLOEXEC) != 0) qWarning("Could not create pipe"); @@ -172,7 +172,7 @@ void Process::setDebug() mDebug = true; } -void Process::error(QProcess::ProcessError error) +void Process::errorOccurred(QProcess::ProcessError error) { switch (error) { case QProcess::FailedToStart: diff --git a/process.h b/process.h index 8b84779..4c073a5 100644 --- a/process.h +++ b/process.h @@ -64,7 +64,7 @@ private slots: void readyReadStandardError(); void readyReadStandardOutput(); void finished(int, QProcess::ExitStatus); - void error(QProcess::ProcessError); + void errorOccurred(QProcess::ProcessError); void incomingConnection(int); private: void forwardProcessOutput(qintptr fd, const QByteArray &data); From fb64b0770925e37942c241597e8ed1070faf3013 Mon Sep 17 00:00:00 2001 From: Dominik Holland Date: Mon, 21 Oct 2024 17:30:29 +0200 Subject: [PATCH 21/27] Don't add empty environment variables when parsing env files Change-Id: Ib49f04260be580c42cc1fa0aa5f7309124fd73ca Reviewed-by: Robert Griebl Reviewed-by: Samuli Piippo --- main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 213339a..eb7a504 100644 --- a/main.cpp +++ b/main.cpp @@ -207,7 +207,9 @@ bool readEnvs(Config *config) const auto line = f.readLine().simplified(); if (!line.startsWith("#")) { const auto index = line.indexOf('='); - config->env[line.left(index)] = line.mid(index + 1); + const auto key = line.left(index); + if (!key.isEmpty()) + config->env[key] = line.mid(index + 1); } } f.close(); From 2a78b4d34b14ddfc21d553a519c6b87b5d02cdba Mon Sep 17 00:00:00 2001 From: Dominik Holland Date: Mon, 21 Oct 2024 17:31:14 +0200 Subject: [PATCH 22/27] Allow specifying multiple environmentFiles in the appcontroller.conf By moving the parseEnv function, this makes it possible to parse the environmentFiles specified in the other controller conf file locations e.g. /var/lib/b2qt/appcontroller.conf.d Change-Id: Ia0610330467b02d21dcf580749d695d526636352 Reviewed-by: Robert Griebl Reviewed-by: Samuli Piippo --- main.cpp | 12 ++++++------ process.h | 1 - 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/main.cpp b/main.cpp index eb7a504..4bc3486 100644 --- a/main.cpp +++ b/main.cpp @@ -195,11 +195,11 @@ static int findFirstFreePort(Utils::PortList &range) return openServer(&s, range); } -bool readEnvs(Config *config) +bool readEnvs(Config *config, const QString &envFile) { - QFile f(config->envFile); + QFile f(envFile); if (!f.open(QFile::ReadOnly)) { - fprintf(stderr, "Could not read environment file: %s\n", qPrintable(config->envFile)); + fprintf(stderr, "Could not read environment file: %s\n", qPrintable(envFile)); return false; } @@ -249,7 +249,9 @@ bool parseConfigFile(Config *config, const QString &fileName) else qWarning() << "Unkonwn value for debuginterface:" << value; } else if (line.startsWith("environmentFile=")) { - config->envFile = line.mid(16).simplified(); + QString envFile = line.mid(16).simplified(); + if (!envFile.isEmpty()) + readEnvs(config, envFile); } } f.close(); @@ -372,8 +374,6 @@ int main(int argc, char **argv) Config config; if (!parseConfigFile(&config, "/etc/appcontroller.conf")) fprintf(stderr, "Failed to parse config file.\n"); - if (!config.envFile.isEmpty()) - readEnvs(&config); while (!args.isEmpty()) { const QString arg(args.takeFirst()); diff --git a/process.h b/process.h index 4c073a5..f0f0e90 100644 --- a/process.h +++ b/process.h @@ -42,7 +42,6 @@ struct Config { QMap env; QStringList args; DebugInterface debugInterface; - QString envFile; }; class Process : public QObject From 6804351bf98535d6bc4fe54b7b1f36b7d5384245 Mon Sep 17 00:00:00 2001 From: Dominik Holland Date: Fri, 25 Oct 2024 11:54:56 +0200 Subject: [PATCH 23/27] Remove quotes when parsing environment variables from a file Change-Id: I0e6797201d7440be5660add16e82a29f535971e6 Reviewed-by: Robert Griebl Reviewed-by: Samuli Piippo --- main.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 4bc3486..5c36b27 100644 --- a/main.cpp +++ b/main.cpp @@ -208,8 +208,11 @@ bool readEnvs(Config *config, const QString &envFile) if (!line.startsWith("#")) { const auto index = line.indexOf('='); const auto key = line.left(index); + auto value = line.mid(index + 1); + if (value.startsWith('"') && value.endsWith('"')) + value = value.mid(1, value.length() - 2); if (!key.isEmpty()) - config->env[key] = line.mid(index + 1); + config->env[key] = value; } } f.close(); From 658dc91cf561e41704619a55fbb1f708decf134e Mon Sep 17 00:00:00 2001 From: Dominik Holland Date: Fri, 25 Oct 2024 13:30:24 +0200 Subject: [PATCH 24/27] Add support for starting the process as another user This allows the application to be run with the correct user and in the correct group and allows to replicate issue which could only happen in such a setup. Change-Id: I105bfd895b65ecca47cff7953d3f899d00e9d784 Reviewed-by: Samuli Piippo Reviewed-by: Robert Griebl --- main.cpp | 5 +++++ process.cpp | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++ process.h | 2 ++ 3 files changed, 66 insertions(+) diff --git a/main.cpp b/main.cpp index 5c36b27..9b78c20 100644 --- a/main.cpp +++ b/main.cpp @@ -255,7 +255,12 @@ bool parseConfigFile(Config *config, const QString &fileName) QString envFile = line.mid(16).simplified(); if (!envFile.isEmpty()) readEnvs(config, envFile); + } else if (line.startsWith("user=")) { + config->user = line.mid(5).simplified(); + } else if (line.startsWith("group=")) { + config->group = line.mid(6).simplified(); } + } f.close(); return true; diff --git a/process.cpp b/process.cpp index 4df8270..24ee409 100644 --- a/process.cpp +++ b/process.cpp @@ -31,7 +31,10 @@ #include #include #include +#include #include +#include +#include bool parseConfigFileDirectory(Config *config, const QString &dirName); static int pipefd[2]; @@ -224,6 +227,62 @@ void Process::startup() parseConfigFileDirectory(&actualConfig, "/var/lib/b2qt/appcontroller.conf.d"); parseConfigFileDirectory(&actualConfig, "/tmp/b2qt/appcontroller.conf.d"); + if (!actualConfig.user.isEmpty()) { + mProcess->setChildProcessModifier([this, actualConfig]() { + if (getuid() != 0) { + fprintf(stderr, "Not running as root, cannot change user\n"); + return; + } + + struct passwd *p; + if ((p = getpwnam(actualConfig.user.toLatin1().constData())) == nullptr) { + fprintf(stderr, "Failed to get user\n"); + return; + } + + if (setgroups(0, nullptr) == -1) + fprintf(stderr, "Failed to clear groups\n"); + + gid_t gid = -1; + QString groupName; + + if (!actualConfig.group.isEmpty()) { + struct group *g; + if ((g = getgrnam(actualConfig.group.toLatin1().constData())) == nullptr) { + fprintf(stderr, "Failed to get group\n"); + return; + } + gid = g->gr_gid; + groupName = g->gr_name; + } else { + struct group *g; + if ((g = getgrgid(p->pw_gid)) == nullptr) { + fprintf(stderr, "Failed to get group\n"); + return; + } + gid = g->gr_gid; + groupName = QString::fromLocal8Bit(g->gr_name); + } + + if (initgroups(actualConfig.user.toLatin1().constData(), gid) == -1) + fprintf(stderr, "Failed to set groups\n"); + + if (setgid(gid) == -1) + fprintf(stderr, "Failed to change group\n"); + + qDebug() << "Changed group to" << groupName << "gid" << gid; + + if (setuid(p->pw_uid) == -1) + printf("Failed to change user\n"); + + qDebug() << "Changed user to" << p->pw_name << "uid" << p->pw_uid; + + // Useful for debugging + // ::system("id"); + // ::system("env"); + }); + } + foreach (const QString &key, actualConfig.env.keys()) { if (!pe.contains(key)) { qDebug() << key << actualConfig.env.value(key); diff --git a/process.h b/process.h index f0f0e90..a2ee737 100644 --- a/process.h +++ b/process.h @@ -42,6 +42,8 @@ struct Config { QMap env; QStringList args; DebugInterface debugInterface; + QString user; + QString group; }; class Process : public QObject From d78fd41bad80b5601bb98d21276ea601855e4d78 Mon Sep 17 00:00:00 2001 From: Dominik Holland Date: Wed, 29 Jan 2025 15:34:19 +0100 Subject: [PATCH 25/27] Add support for wrapper command definition This is useful when you want to use a specific command to start your application e.g. systemd-run This also helps to run the application in a specific slice to be part of the correct cgroup. Change-Id: I74f29f6381ba5ff0fec8e8d9ad9f9f830dbbab81 Reviewed-by: Robert Griebl Reviewed-by: Samuli Piippo --- main.cpp | 2 ++ process.cpp | 13 +++++++++++-- process.h | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/main.cpp b/main.cpp index 9b78c20..a6eb778 100644 --- a/main.cpp +++ b/main.cpp @@ -259,6 +259,8 @@ bool parseConfigFile(Config *config, const QString &fileName) config->user = line.mid(5).simplified(); } else if (line.startsWith("group=")) { config->group = line.mid(6).simplified(); + } else if (line.startsWith("wrapperCmd=")) { + config->wrapperCmd = line.mid(11).simplified(); } } diff --git a/process.cpp b/process.cpp index 24ee409..f29d1c8 100644 --- a/process.cpp +++ b/process.cpp @@ -297,9 +297,18 @@ void Process::startup() args.append(actualConfig.args); mProcess->setProcessEnvironment(pe); - mBinary = args.first(); - args.removeFirst(); + if (actualConfig.wrapperCmd.isEmpty()) { + mBinary = args.first(); + args.removeFirst(); + } else { + QStringList wrapper = actualConfig.wrapperCmd.split(" "); + mBinary = wrapper.first(); + wrapper.removeFirst(); + args = wrapper + args; + } + qDebug() << mBinary << args; + mProcess->start(mBinary, args); } diff --git a/process.h b/process.h index a2ee737..ecf8ee9 100644 --- a/process.h +++ b/process.h @@ -44,6 +44,7 @@ struct Config { DebugInterface debugInterface; QString user; QString group; + QString wrapperCmd; }; class Process : public QObject From f912b6244dbb5d8916c0bb2d317b2bb9914a772a Mon Sep 17 00:00:00 2001 From: Dominik Holland Date: Mon, 3 Feb 2025 12:25:16 +0100 Subject: [PATCH 26/27] Add a way to clear specific environment variables Currently the configured environment variables are only set if they don't override an existing one. This is done to allow setting an environment variable in QtCreator. This is a problem when a specific environment variable is defined in the root shell e.g. XDG_RUNTIME_DIR, but the actual process should use another value, specified using the 'env' key. To solve this a new 'clearEnv' setting gets introduced which makes it possible to clear specific environment variables before applying the new environment variables. Change-Id: I319db570a4e410b8f2716adcec9be882d89f4b1e Reviewed-by: Robert Griebl --- main.cpp | 2 ++ process.cpp | 4 ++++ process.h | 1 + 3 files changed, 7 insertions(+) diff --git a/main.cpp b/main.cpp index a6eb778..496f3f1 100644 --- a/main.cpp +++ b/main.cpp @@ -261,6 +261,8 @@ bool parseConfigFile(Config *config, const QString &fileName) config->group = line.mid(6).simplified(); } else if (line.startsWith("wrapperCmd=")) { config->wrapperCmd = line.mid(11).simplified(); + } else if (line.startsWith("clearEnv=")) { + config->clearEnv.append(line.mid(9).simplified()); } } diff --git a/process.cpp b/process.cpp index f29d1c8..c6fbe2e 100644 --- a/process.cpp +++ b/process.cpp @@ -283,6 +283,10 @@ void Process::startup() }); } + foreach (const QString &key, actualConfig.clearEnv) { + pe.remove(key); + } + foreach (const QString &key, actualConfig.env.keys()) { if (!pe.contains(key)) { qDebug() << key << actualConfig.env.value(key); diff --git a/process.h b/process.h index ecf8ee9..17754ac 100644 --- a/process.h +++ b/process.h @@ -40,6 +40,7 @@ struct Config { QString base; QString platform; QMap env; + QStringList clearEnv; QStringList args; DebugInterface debugInterface; QString user; From 92ee96905ee914295f31590ec67595bea97a613a Mon Sep 17 00:00:00 2001 From: Dominik Holland Date: Tue, 4 Feb 2025 17:07:40 +0100 Subject: [PATCH 27/27] Introduce a new "--no-wrapper" command-line flag Change-Id: Ie591d109d5d3bbbb862e54e1c35c49a13f694be4 Reviewed-by: Robert Griebl --- main.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 496f3f1..6f05471 100644 --- a/main.cpp +++ b/main.cpp @@ -52,7 +52,7 @@ static void usage() printf("appcontroller [--debug-gdb] [--debug-gdb-port ]" " [--debug-qml] [--debug-qml-port ] [--qml-debug-services ]" " [--profile-perf ] [--port-range ] [--stop] [--launch] [--show-platfrom]" - " [--make-default] [--remove-default] [--print-debug] [--version] [--detach]" + " [--make-default] [--no-wrapper] [--remove-default] [--print-debug] [--version] [--detach]" " [executable] [arguments]\n" "\n" "--port-range Port range to use for debugging connections\n" @@ -69,6 +69,7 @@ static void usage() " application\n" "--show-platform Show platform information\n" "--make-default Make this application the default on boot\n" + "--no-wrapper Start the application without the configured wrapper command\n" "--remove-default Restore the default application\n" "--version Print version information\n" "--detach Start application as usual, then go into background\n" @@ -460,6 +461,8 @@ int main(int argc, char **argv) if (!makeDefault(args.takeFirst())) return 1; return 0; + } else if (arg == "--no-wrapper") { + config.wrapperCmd.clear(); } else if (arg == "--remove-default") { if (removeDefault()) return 0;