summaryrefslogtreecommitdiffstats
path: root/main.cpp
diff options
context:
space:
mode:
authorRainer Keller <rainer.keller@digia.com>2013-04-17 10:45:51 +0200
committerRainer Keller <rainer.keller@digia.com>2013-04-17 10:45:51 +0200
commit2401f709701f3e0d771f7dfd492cc16ab67a7d8d (patch)
tree48f4862bc572130514c91382a02cfcda8166e335 /main.cpp
parent9a7f2e2ee373e9f8a6dd57ab89e963d8952bb94c (diff)
Add debugging support
Diffstat (limited to 'main.cpp')
-rw-r--r--main.cpp210
1 files changed, 88 insertions, 122 deletions
diff --git a/main.cpp b/main.cpp
index 71e37cd..e87904d 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,102 +1,92 @@
+#include "process.h"
#include <QCoreApplication>
-#include <QFile>
-#include <QDebug>
#include <QTcpServer>
+#include <QProcess>
#include <errno.h>
-#include <unistd.h>
#include <QStringList>
-#include <fcntl.h>
+#include <QSocketNotifier>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
#define PID_FILE "/data/user/.appcontroller"
-static void loadDefaults(QStringList &defaultArgs)
-{
- QFile f("/system/bin/appcontroller.conf");
-
- if (!f.open(QFile::ReadOnly)) {
- qWarning("Could not read config file.");
- return;
- }
+static int serverSocket = -1;
- while (!f.atEnd()) {
- QString line = f.readLine();
- if (line.startsWith("env=")) {
- QString sub = line.mid(4).simplified();
- int index = sub.indexOf('=');
- if (index < 2) {
- // ignore
- } else {
- setenv(sub.left(index).toLocal8Bit().constData(), sub.mid(index+1).toLocal8Bit().constData(), 1);
- qDebug() << sub.left(index) << sub.mid(index+1);
- }
- } else if (line.startsWith("append=")) {
- defaultArgs += line.mid(7).simplified();
- qDebug() << defaultArgs;
- }
- }
+static const char socketPath[] = "#Boot2Qt_appcontroller";
- // env=...
- // append=...
+static void setupAddressStruct(struct sockaddr_un &address)
+{
+ address.sun_family = AF_UNIX;
+ memset(address.sun_path, 0, sizeof(address.sun_path));
+ strncpy(address.sun_path, socketPath, sizeof(address.sun_path)-1);
+ address.sun_path[0] = 0;
}
-static pid_t lastPID(QFile &f)
+static int connectSocket()
{
- f.seek(0);
- bool ok;
- pid_t pid = f.readAll().toUInt(&ok);
- if (!ok) {
- qWarning("Invalid last PID.");
- return 0;
- }
+ int create_socket;
+ struct sockaddr_un address;
- return pid;
-}
+ if ((create_socket=socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ perror("Could not create socket");
+ return -1;
+ }
-static void stop(QFile &file)
-{
- pid_t pid = lastPID(file);
- if (pid == 0)
- return;
-
- int rc = ::kill(pid, SIGTERM);
- if (rc != 0) {
- if (errno == ESRCH)
- return;
- else {
- qWarning("Kill not permitted/invalid");
- return;
- }
- }
+ setupAddressStruct(address);
- sleep(1);
+ if (connect(create_socket, (struct sockaddr *) &address, sizeof (address)) != 0) {
+ perror("Could not connect");
+ return -1;
+ }
+ close(create_socket);
+ return 0;
+}
- rc = ::kill(pid, SIGKILL);
- if (rc != 0) {
- if (errno == ESRCH)
- return;
- else {
- qWarning("Kill not permitted/invalid");
- return;
- }
- }
+static int createServerSocket()
+{
+ struct sockaddr_un address;
+
+ if ((serverSocket=socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ perror("Could not create socket");
+ return -1;
+ }
+
+ setupAddressStruct(address);
+
+ if (bind(serverSocket, (struct sockaddr *) &address, sizeof (address)) != 0) {
+ if (errno != EADDRINUSE) {
+ perror("Could not bind socket");
+ return -1;
+ }
+
+ if (connectSocket() != 0) {
+ fprintf(stderr, "Failed to connect to process\n");
+ return -1;
+ }
+
+ usleep(500000);
+ // try again
+ if (bind(serverSocket, (struct sockaddr *) &address, sizeof (address)) != 0) {
+ perror("Could not bind socket");
+ return -1;
+ }
+ }
+
+ if (listen(serverSocket, 5) != 0) {
+ perror("Could not listen");
+ return -1;
+ }
+
+ return 0;
}
-int lockFile(int handle)
+static void stop()
{
- struct flock lock;
- lock.l_type = F_WRLCK | F_RDLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 100;
- int rc = fcntl(handle, F_SETLKW, &lock);
- if (rc != 0) {
- perror("Locking failed");
- return 1;
- }
- return 0;
+ connectSocket();
}
-int findFirstFreePort(int start, int end)
+static int findFirstFreePort(int start, int end)
{
QTcpServer s;
@@ -112,6 +102,7 @@ int main(int argc, char **argv)
QCoreApplication app(argc, argv);
QStringList defaultArgs;
QString binary;
+ bool debug = false;
QStringList args = app.arguments();
args.removeFirst();
@@ -120,18 +111,6 @@ int main(int argc, char **argv)
return 1;
}
- QFile f(PID_FILE);
- if (!f.open(QFile::ReadWrite)) {
- qDebug() << "Could not open PID file.";
- return 1;
- }
-
- if (lockFile(f.handle()) != 0) {
- qDebug() << "Could not get lock.";
- return 1;
- }
- qDebug() << "File locked";
-
while (!args.isEmpty()) {
if (args[0] == "--start") {
if (args.size() < 2) {
@@ -144,10 +123,10 @@ int main(int argc, char **argv)
qWarning("App path is empty");
return 1;
}
- stop(f);
- loadDefaults(defaultArgs);
- defaultArgs.push_front(binary);
+ defaultArgs.append(args);
+ break;
} else if (args[0] == "--start-debug") {
+ debug = true;
if (args.size() < 4) {
qWarning("--start-debug requires arguments: start-port-range end-port-range and executable");
return 1;
@@ -166,19 +145,20 @@ int main(int argc, char **argv)
qWarning("App path is empty");
return 1;
}
- stop(f);
- loadDefaults(defaultArgs);
int port = findFirstFreePort(range_start, range_end);
if (port < 0) {
qWarning("Could not find an unsued port in range");
return 1;
}
- defaultArgs.push_front(binary);
- defaultArgs.push_front("localhost" + QString::number(port));
+ defaultArgs.push_front("localhost:" + QString::number(port));
defaultArgs.push_front("gdbserver");
+ defaultArgs.append(args);
+ setpgid(0,0); // must be called before setsid()
+ setsid();
+ break;
} else if (args[0] == "--stop") {
- stop(f);
+ stop();
return 0;
} else {
qWarning("unknown argument: %s", args.first().toLocal8Bit().constData());
@@ -187,32 +167,18 @@ int main(int argc, char **argv)
args.removeFirst();
}
- char **arglist = new char*[defaultArgs.size()+1];
- for (int i = 0; i < defaultArgs.size(); i++) {
- arglist[i] = strdup(defaultArgs[i].toLocal8Bit().constData());
- }
- arglist[defaultArgs.size()] = 0;
- defaultArgs.clear();
-
- if (!f.seek(0)) {
- qDebug() << "Could not seek.";
- return 1;
- }
- if (!f.resize(0)) {
- qDebug() << "Could not resize.";
+ if (createServerSocket() != 0) {
+ fprintf(stderr, "Could not create serversocket\n");
return 1;
}
- QByteArray data = QString::number(getpid()).toLatin1();
-
- if (f.write(data) != data.size()) {
- qDebug() << "Write failed.";
- return 1;
- }
- f.close();
- qDebug() << "Starting binary";
-
- execv(binary.toLocal8Bit().constData(), arglist);
-
+ Process process;
+ if (debug)
+ process.setDebug();
+ process.setSocketNotifier(new QSocketNotifier(serverSocket, QSocketNotifier::Read, &process));
+ process.start(defaultArgs);
+ app.exec();
+ close(serverSocket);
return 0;
}
+