summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKalle Viironen <kalle.viironen@digia.com>2014-02-21 12:00:48 +0200
committerKalle Viironen <kalle.viironen@digia.com>2014-02-21 12:01:34 +0200
commit544ffcec55b53e09978f6b9a7050c4a24f46870f (patch)
treea476cd83aaf6cbe4149f2b2aa0ceebaaa88bb586
parent178722f2fb757b89734f612a835b800ed59975da (diff)
parent602acb292c76e01e00382d14d387ea2ec367927c (diff)
Merge branch 'stable' into releaseQtEE_v2.1.0QtEE_v2.0.0
* stable: Check git hash/tag only if we are in git repo Sync filesystems after modification Change copyright to 2014 Let user override default variables Start process with interactive process environment Add license headers Provide appcontroller with version information Analyze binary if start fails Export 'base' and 'platform' to process environment Add option to configure gdb network name Change-Id: Iccc81b1bbea29572d13516e889634c91d54df46a
-rw-r--r--appcontroller.pro21
-rw-r--r--main.cpp38
-rw-r--r--portlist.cpp29
-rw-r--r--portlist.h29
-rw-r--r--process.cpp154
-rw-r--r--process.h26
6 files changed, 251 insertions, 46 deletions
diff --git a/appcontroller.pro b/appcontroller.pro
index 7ad5acc..b467652 100644
--- a/appcontroller.pro
+++ b/appcontroller.pro
@@ -15,3 +15,24 @@ android {
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 0a3e93d..676b4ab 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,3 +1,21 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of QtEnterprise Embedded.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
#include "process.h"
#include "portlist.h"
#include <QCoreApplication>
@@ -120,6 +138,7 @@ static Config parseConfigFile()
{
Config config;
config.base = config.platform = QLatin1String("unknown");
+ config.debugInterface = Config::LocalDebugInterface;
#ifdef Q_OS_ANDROID
QFile f("/system/bin/appcontroller.conf");
@@ -147,6 +166,14 @@ static Config parseConfigFile()
config.base = line.mid(5).simplified();
} else if (line.startsWith("platform=")) {
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;
+ else if (value == "public")
+ config.debugInterface = Config::PublicDebugInterface;
+ else
+ qWarning() << "Unkonwn value for debuginterface:" << value;
}
}
f.close();
@@ -160,6 +187,7 @@ static bool removeDefault()
fprintf(stderr, "Could not remove default application.\n");
return false;
}
+ sync();
}
return true;
}
@@ -180,6 +208,7 @@ static bool makeDefault(const QString &filepath)
fprintf(stderr, "Could not link default application.\n");
return false;
}
+ sync();
return true;
}
@@ -245,6 +274,9 @@ int main(int argc, char **argv)
return 1;
} else if (arg == "--print-debug") {
config.flags |= Config::PrintDebugMessages;
+ } else if (arg == "--version") {
+ printf("Appcontroller version: " GIT_VERSION "\nGit revision: " GIT_HASH "\n");
+ return 0;
} else {
args.prepend(arg);
break;
@@ -283,7 +315,11 @@ int main(int argc, char **argv)
defaultArgs.append(args);
if (useGDB) {
- defaultArgs.push_front("localhost:" + QString::number(gdbDebugPort));
+ QString interface;
+ if (config.debugInterface == Config::LocalDebugInterface)
+ interface = QLatin1String("localhost");
+
+ defaultArgs.push_front(interface + ":" + QString::number(gdbDebugPort));
defaultArgs.push_front("gdbserver");
}
diff --git a/portlist.cpp b/portlist.cpp
index 054a9a2..e0258c9 100644
--- a/portlist.cpp
+++ b/portlist.cpp
@@ -1,29 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of Qt Creator.
+** This file is part of QtEnterprise Embedded.
**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: 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
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/portlist.h b/portlist.h
index 2146c39..4846bf0 100644
--- a/portlist.h
+++ b/portlist.h
@@ -1,29 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of Qt Creator.
+** This file is part of QtEnterprise Embedded.
**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: 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
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/process.cpp b/process.cpp
index b79594f..32ad853 100644
--- a/process.cpp
+++ b/process.cpp
@@ -1,3 +1,21 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of QtEnterprise Embedded.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
#include "process.h"
#include <QCoreApplication>
#include <unistd.h>
@@ -7,6 +25,7 @@
#include <sys/socket.h>
#include <signal.h>
#include <fcntl.h>
+#include <QFileInfo>
static int pipefd[2];
@@ -15,6 +34,53 @@ static void signalhandler(int)
write(pipefd[1], " ", 1);
}
+static bool analyzeBinary(const QString &binary)
+{
+ QFileInfo fi(binary);
+ if (!fi.exists()) {
+ printf("Binary does not exist.\n");
+ return false;
+ }
+ if (!fi.isFile()) {
+ printf("Binary is not a file.\n");
+ return false;
+ }
+ if (!fi.isReadable()) {
+ printf("Binary is not readable.\n");
+ return false;
+ }
+ if (!fi.isExecutable()) {
+ printf("Binary is not executable.\n");
+ return false;
+ }
+
+ if (fi.size() < 4) {
+ printf("Binary is smaller than 4 bytes.\n");
+ return false;
+ }
+
+ QFile f(binary);
+ if (!f.open(QFile::ReadOnly)) {
+ printf("Could not open binary to analyze.\n");
+ return false;
+ }
+
+ QByteArray elfHeader = f.read(4);
+ f.close();
+
+ if (elfHeader.size() < 4) {
+ printf("Failed to read ELF header.\n");
+ return false;
+ }
+
+ if (elfHeader != QByteArray::fromHex("7f454C46")) { // 0x7f ELF
+ printf("Binary is not an ELF file.\n");
+ return false;
+ }
+
+ return true;
+}
+
Process::Process()
: QObject(0)
, mProcess(new QProcess(this))
@@ -81,6 +147,7 @@ void Process::error(QProcess::ProcessError error)
switch (error) {
case QProcess::FailedToStart:
printf("Failed to start\n");
+ analyzeBinary(mBinary);
break;
case QProcess::Crashed:
printf("Crashed\n");
@@ -111,20 +178,30 @@ void Process::finished(int exitCode, QProcess::ExitStatus exitStatus)
void Process::startup(QStringList args)
{
+#ifdef Q_OS_ANDROID
+ QProcessEnvironment pe = interactiveProcessEnvironment();
+#else
QProcessEnvironment pe = QProcessEnvironment::systemEnvironment();
+#endif
foreach (const QString &key, mConfig.env.keys()) {
- qDebug() << key << mConfig.env.value(key);
- pe.insert(key, mConfig.env.value(key));
+ if (!pe.contains(key)) {
+ qDebug() << key << mConfig.env.value(key);
+ pe.insert(key, mConfig.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);
args.append(mConfig.args);
mProcess->setProcessEnvironment(pe);
- QString binary = args.first();
+ mBinary = args.first();
args.removeFirst();
- qDebug() << binary << args;
- mProcess->start(binary, args);
+ qDebug() << mBinary << args;
+ mProcess->start(mBinary, args);
}
void Process::start(const QStringList &args)
@@ -168,3 +245,70 @@ void Process::setConfig(const Config &config)
{
mConfig = config;
}
+
+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<QByteArray> 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 99e5778..290fde4 100644
--- a/process.h
+++ b/process.h
@@ -1,3 +1,21 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of QtEnterprise Embedded.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
#include <QObject>
#include <QProcess>
#include <QMap>
@@ -10,6 +28,11 @@ struct Config {
};
Q_DECLARE_FLAGS(Flags, Flag)
+ enum DebugInterface{
+ LocalDebugInterface,
+ PublicDebugInterface
+ };
+
Config() : flags(0) { }
QString base;
@@ -17,6 +40,7 @@ struct Config {
QMap<QString,QString> env;
QStringList args;
Flags flags;
+ DebugInterface debugInterface;
};
class Process : public QObject
@@ -39,8 +63,10 @@ private slots:
void incomingConnection(int);
private:
void startup(QStringList);
+ QProcessEnvironment interactiveProcessEnvironment() const;
QProcess *mProcess;
int mDebuggee;
bool mDebug;
Config mConfig;
+ QString mBinary;
};