forked from qt-creator/qt-creator
ProjectExplorer: Introduce generic application runner.
This class aims to be a flexible worker class for SSH-based run controls. It supersedes AbstractRemoteLinuxApplicationRunner as well as all of its derived classes, while having no RemoteLinux dependencies itself. Change-Id: If24f03a32126b36fc3d0b253a1615ad0af5f2b46 Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
@@ -11,7 +11,6 @@ HEADERS += \
|
|||||||
debianmanager.h \
|
debianmanager.h \
|
||||||
maemoconstants.h \
|
maemoconstants.h \
|
||||||
maemorunconfigurationwidget.h \
|
maemorunconfigurationwidget.h \
|
||||||
maemoruncontrol.h \
|
|
||||||
maemorunfactories.h \
|
maemorunfactories.h \
|
||||||
maemosettingspages.h \
|
maemosettingspages.h \
|
||||||
maemopackagecreationstep.h \
|
maemopackagecreationstep.h \
|
||||||
@@ -20,8 +19,6 @@ HEADERS += \
|
|||||||
maemoqemumanager.h \
|
maemoqemumanager.h \
|
||||||
maemodeploystepfactory.h \
|
maemodeploystepfactory.h \
|
||||||
maemoglobal.h \
|
maemoglobal.h \
|
||||||
maemosshrunner.h \
|
|
||||||
maemodebugsupport.h \
|
|
||||||
maemoremotemountsmodel.h \
|
maemoremotemountsmodel.h \
|
||||||
maemomountspecification.h \
|
maemomountspecification.h \
|
||||||
maemoremotemounter.h \
|
maemoremotemounter.h \
|
||||||
@@ -52,13 +49,13 @@ HEADERS += \
|
|||||||
maddedevicetester.h \
|
maddedevicetester.h \
|
||||||
maddedeviceconfigurationfactory.h \
|
maddedeviceconfigurationfactory.h \
|
||||||
maddedevice.h \
|
maddedevice.h \
|
||||||
rpmmanager.h
|
rpmmanager.h \
|
||||||
|
maemoapplicationrunnerhelperactions.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
maddeplugin.cpp \
|
maddeplugin.cpp \
|
||||||
debianmanager.cpp \
|
debianmanager.cpp \
|
||||||
maemorunconfigurationwidget.cpp \
|
maemorunconfigurationwidget.cpp \
|
||||||
maemoruncontrol.cpp \
|
|
||||||
maemorunfactories.cpp \
|
maemorunfactories.cpp \
|
||||||
maemosettingspages.cpp \
|
maemosettingspages.cpp \
|
||||||
maemopackagecreationstep.cpp \
|
maemopackagecreationstep.cpp \
|
||||||
@@ -67,8 +64,6 @@ SOURCES += \
|
|||||||
maemoqemumanager.cpp \
|
maemoqemumanager.cpp \
|
||||||
maemodeploystepfactory.cpp \
|
maemodeploystepfactory.cpp \
|
||||||
maemoglobal.cpp \
|
maemoglobal.cpp \
|
||||||
maemosshrunner.cpp \
|
|
||||||
maemodebugsupport.cpp \
|
|
||||||
maemoremotemountsmodel.cpp \
|
maemoremotemountsmodel.cpp \
|
||||||
maemomountspecification.cpp \
|
maemomountspecification.cpp \
|
||||||
maemoremotemounter.cpp \
|
maemoremotemounter.cpp \
|
||||||
@@ -98,7 +93,8 @@ SOURCES += \
|
|||||||
maddedevicetester.cpp \
|
maddedevicetester.cpp \
|
||||||
maemorunconfiguration.cpp \
|
maemorunconfiguration.cpp \
|
||||||
maddedevice.cpp \
|
maddedevice.cpp \
|
||||||
rpmmanager.cpp
|
rpmmanager.cpp \
|
||||||
|
maemoapplicationrunnerhelperactions.cpp
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
maemopackagecreationwidget.ui \
|
maemopackagecreationwidget.ui \
|
||||||
|
@@ -31,8 +31,6 @@ QtcPlugin {
|
|||||||
"maddeuploadandinstallpackagesteps.cpp",
|
"maddeuploadandinstallpackagesteps.cpp",
|
||||||
"maddeuploadandinstallpackagesteps.h",
|
"maddeuploadandinstallpackagesteps.h",
|
||||||
"maemoconstants.h",
|
"maemoconstants.h",
|
||||||
"maemodebugsupport.cpp",
|
|
||||||
"maemodebugsupport.h",
|
|
||||||
"maemodeploybymountsteps.cpp",
|
"maemodeploybymountsteps.cpp",
|
||||||
"maemodeploybymountsteps.h",
|
"maemodeploybymountsteps.h",
|
||||||
"maemodeployconfigurationwidget.cpp",
|
"maemodeployconfigurationwidget.cpp",
|
||||||
@@ -108,14 +106,10 @@ QtcPlugin {
|
|||||||
"maemorunconfiguration.h",
|
"maemorunconfiguration.h",
|
||||||
"maemorunconfigurationwidget.cpp",
|
"maemorunconfigurationwidget.cpp",
|
||||||
"maemorunconfigurationwidget.h",
|
"maemorunconfigurationwidget.h",
|
||||||
"maemoruncontrol.cpp",
|
|
||||||
"maemoruncontrol.h",
|
|
||||||
"maemorunfactories.cpp",
|
"maemorunfactories.cpp",
|
||||||
"maemorunfactories.h",
|
"maemorunfactories.h",
|
||||||
"maemosettingspages.cpp",
|
"maemosettingspages.cpp",
|
||||||
"maemosettingspages.h",
|
"maemosettingspages.h",
|
||||||
"maemosshrunner.cpp",
|
|
||||||
"maemosshrunner.h",
|
|
||||||
"qt-maemo.qrc",
|
"qt-maemo.qrc",
|
||||||
"qt4maemodeployconfiguration.cpp",
|
"qt4maemodeployconfiguration.cpp",
|
||||||
"qt4maemodeployconfiguration.h",
|
"qt4maemodeployconfiguration.h",
|
||||||
@@ -124,6 +118,8 @@ QtcPlugin {
|
|||||||
"debianmanager.h",
|
"debianmanager.h",
|
||||||
"debianmanager.cpp",
|
"debianmanager.cpp",
|
||||||
"rpmmanager.h",
|
"rpmmanager.h",
|
||||||
"rpmmanager.cpp"
|
"rpmmanager.cpp",
|
||||||
|
"maemoapplicationrunnerhelperactions.h",
|
||||||
|
"maemoapplicationrunnerhelperactions.cpp"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
148
src/plugins/madde/maemoapplicationrunnerhelperactions.cpp
Normal file
148
src/plugins/madde/maemoapplicationrunnerhelperactions.cpp
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: http://www.qt-project.org/
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
**
|
||||||
|
** 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, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** Other Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used in accordance with the terms and
|
||||||
|
** conditions contained in a signed written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#include "maemoapplicationrunnerhelperactions.h"
|
||||||
|
|
||||||
|
#include "maemomountspecification.h"
|
||||||
|
#include "maemoremotemounter.h"
|
||||||
|
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
using namespace ProjectExplorer;
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
|
namespace Madde {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
MaemoPreRunAction::MaemoPreRunAction(const IDevice::ConstPtr &device, const FileName &maddeRoot,
|
||||||
|
const QList<MaemoMountSpecification> &mountSpecs, QObject *parent)
|
||||||
|
: DeviceApplicationHelperAction(parent), m_mounter(new MaemoRemoteMounter(this))
|
||||||
|
{
|
||||||
|
m_mounter->setParameters(device, maddeRoot);
|
||||||
|
foreach (const MaemoMountSpecification &m, mountSpecs)
|
||||||
|
m_mounter->addMountSpecification(m, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoPreRunAction::handleMounted()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_isRunning, return);
|
||||||
|
|
||||||
|
setFinished(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoPreRunAction::handleError(const QString &message)
|
||||||
|
{
|
||||||
|
if (!m_isRunning)
|
||||||
|
return;
|
||||||
|
|
||||||
|
emit reportError(message);
|
||||||
|
setFinished(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoPreRunAction::start()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(!m_isRunning, return);
|
||||||
|
|
||||||
|
connect(m_mounter, SIGNAL(debugOutput(QString)), SIGNAL(reportProgress(QString)));
|
||||||
|
connect(m_mounter, SIGNAL(reportProgress(QString)), SIGNAL(reportProgress(QString)));
|
||||||
|
connect(m_mounter, SIGNAL(mounted()), SLOT(handleMounted()));
|
||||||
|
connect(m_mounter, SIGNAL(error(QString)), SLOT(handleError(QString)));
|
||||||
|
m_isRunning = true;
|
||||||
|
m_mounter->mount();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoPreRunAction::stop()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_isRunning, return);
|
||||||
|
|
||||||
|
m_mounter->stop();
|
||||||
|
setFinished(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoPreRunAction::setFinished(bool success)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_isRunning, return);
|
||||||
|
|
||||||
|
m_mounter->disconnect(this);
|
||||||
|
m_isRunning = false;
|
||||||
|
emit finished(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
MaemoPostRunAction::MaemoPostRunAction(MaemoRemoteMounter *mounter, QObject *parent)
|
||||||
|
: DeviceApplicationHelperAction(parent), m_mounter(mounter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoPostRunAction::handleUnmounted()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_isRunning, return);
|
||||||
|
|
||||||
|
setFinished(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoPostRunAction::handleError(const QString &message)
|
||||||
|
{
|
||||||
|
if (!m_isRunning)
|
||||||
|
return;
|
||||||
|
|
||||||
|
emit reportError(message);
|
||||||
|
setFinished(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoPostRunAction::start()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(!m_isRunning, return);
|
||||||
|
|
||||||
|
connect(m_mounter, SIGNAL(debugOutput(QString)), SIGNAL(reportProgress(QString)));
|
||||||
|
connect(m_mounter, SIGNAL(reportProgress(QString)), SIGNAL(reportProgress(QString)));
|
||||||
|
connect(m_mounter, SIGNAL(unmounted()), SLOT(handleUnmounted()));
|
||||||
|
connect(m_mounter, SIGNAL(error(QString)), SLOT(handleError(QString)));
|
||||||
|
m_isRunning = true;
|
||||||
|
m_mounter->unmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoPostRunAction::stop()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_isRunning, return);
|
||||||
|
|
||||||
|
m_mounter->stop();
|
||||||
|
setFinished(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaemoPostRunAction::setFinished(bool success)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_isRunning, return);
|
||||||
|
|
||||||
|
m_mounter->disconnect(this);
|
||||||
|
m_isRunning = false;
|
||||||
|
emit finished(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Madde
|
@@ -6,6 +6,7 @@
|
|||||||
**
|
**
|
||||||
** Contact: http://www.qt-project.org/
|
** Contact: http://www.qt-project.org/
|
||||||
**
|
**
|
||||||
|
**
|
||||||
** GNU Lesser General Public License Usage
|
** GNU Lesser General Public License Usage
|
||||||
**
|
**
|
||||||
** This file may be used under the terms of the GNU Lesser General Public
|
** This file may be used under the terms of the GNU Lesser General Public
|
||||||
@@ -26,54 +27,65 @@
|
|||||||
**
|
**
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
#ifndef MAEMOAPPLICATIONRUNNERHELPERACTIONS_H
|
||||||
|
#define MAEMOAPPLICATIONRUNNERHELPERACTIONS_H
|
||||||
|
|
||||||
#ifndef MAEMOSSHRUNNER_H
|
#include <projectexplorer/devicesupport/deviceapplicationrunner.h>
|
||||||
#define MAEMOSSHRUNNER_H
|
|
||||||
|
|
||||||
#include "maemomountspecification.h"
|
#include <QList>
|
||||||
|
|
||||||
#include <remotelinux/remotelinuxapplicationrunner.h>
|
namespace Utils { class FileName; }
|
||||||
|
|
||||||
namespace Madde {
|
namespace Madde {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
class MaemoMountSpecification;
|
||||||
class MaemoRemoteMounter;
|
class MaemoRemoteMounter;
|
||||||
class MaemoRunConfiguration;
|
|
||||||
|
|
||||||
class MaemoSshRunner : public RemoteLinux::AbstractRemoteLinuxApplicationRunner
|
class MaemoPreRunAction : public ProjectExplorer::DeviceApplicationHelperAction
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MaemoSshRunner(QObject *parent, MaemoRunConfiguration *runConfig);
|
MaemoPreRunAction(const ProjectExplorer::IDevice::ConstPtr &device,
|
||||||
|
const Utils::FileName &maddeRoot, const QList<MaemoMountSpecification> &mountSpecs,
|
||||||
|
QObject *parent = 0);
|
||||||
|
|
||||||
signals:
|
MaemoRemoteMounter *mounter() const { return m_mounter; }
|
||||||
void mountDebugOutput(const QString &output);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleMounted();
|
void handleMounted();
|
||||||
void handleUnmounted();
|
void handleError(const QString &message);
|
||||||
void handleMounterError(const QString &errorMsg);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum MountState { InactiveMountState, InitialUnmounting, Mounting, Mounted, PostRunUnmounting };
|
void start();
|
||||||
|
void stop();
|
||||||
|
|
||||||
bool canRun(QString &whyNot) const;
|
void setFinished(bool success);
|
||||||
void doDeviceSetup();
|
|
||||||
void doAdditionalInitialCleanup();
|
|
||||||
void doAdditionalInitializations();
|
|
||||||
void doPostRunCleanup();
|
|
||||||
void doAdditionalConnectionErrorHandling();
|
|
||||||
|
|
||||||
void mount();
|
|
||||||
void unmount();
|
|
||||||
|
|
||||||
MaemoRemoteMounter * const m_mounter;
|
MaemoRemoteMounter * const m_mounter;
|
||||||
QList<MaemoMountSpecification> m_mountSpecs;
|
bool m_isRunning;
|
||||||
MountState m_mountState;
|
};
|
||||||
int m_qtId;
|
|
||||||
|
class MaemoPostRunAction : public ProjectExplorer::DeviceApplicationHelperAction
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
MaemoPostRunAction(MaemoRemoteMounter *mounter, QObject *parent = 0);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleUnmounted();
|
||||||
|
void handleError(const QString &message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
void setFinished(bool success);
|
||||||
|
|
||||||
|
MaemoRemoteMounter * const m_mounter;
|
||||||
|
bool m_isRunning;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Madde
|
} // namespace Madde
|
||||||
|
|
||||||
#endif // MAEMOSSHRUNNER_H
|
#endif // MAEMOAPPLICATIONRUNNERHELPERACTIONS_H
|
@@ -1,54 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator
|
|
||||||
**
|
|
||||||
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
|
||||||
**
|
|
||||||
** Contact: http://www.qt-project.org/
|
|
||||||
**
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
**
|
|
||||||
** 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, Nokia gives you certain additional
|
|
||||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
** Other Usage
|
|
||||||
**
|
|
||||||
** Alternatively, this file may be used in accordance with the terms and
|
|
||||||
** conditions contained in a signed written agreement between you and Nokia.
|
|
||||||
**
|
|
||||||
**
|
|
||||||
**************************************************************************/
|
|
||||||
#include "maemodebugsupport.h"
|
|
||||||
|
|
||||||
#include "maemorunconfiguration.h"
|
|
||||||
#include "maemosshrunner.h"
|
|
||||||
|
|
||||||
#include <remotelinux/linuxdeviceconfiguration.h>
|
|
||||||
|
|
||||||
using namespace RemoteLinux;
|
|
||||||
|
|
||||||
namespace Madde {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
MaemoDebugSupport::MaemoDebugSupport(MaemoRunConfiguration *runConfig, Debugger::DebuggerEngine *engine)
|
|
||||||
: AbstractRemoteLinuxDebugSupport(runConfig, engine),
|
|
||||||
m_runner(new MaemoSshRunner(this, runConfig))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MaemoDebugSupport::~MaemoDebugSupport()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRemoteLinuxApplicationRunner *MaemoDebugSupport::runner() const { return m_runner; }
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace Madde
|
|
@@ -1,56 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator
|
|
||||||
**
|
|
||||||
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
|
||||||
**
|
|
||||||
** Contact: http://www.qt-project.org/
|
|
||||||
**
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
**
|
|
||||||
** 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, Nokia gives you certain additional
|
|
||||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
** Other Usage
|
|
||||||
**
|
|
||||||
** Alternatively, this file may be used in accordance with the terms and
|
|
||||||
** conditions contained in a signed written agreement between you and Nokia.
|
|
||||||
**
|
|
||||||
**
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef MAEMODEBUGSUPPORT_H
|
|
||||||
#define MAEMODEBUGSUPPORT_H
|
|
||||||
|
|
||||||
#include <remotelinux/remotelinuxdebugsupport.h>
|
|
||||||
|
|
||||||
namespace Madde {
|
|
||||||
namespace Internal {
|
|
||||||
class MaemoRunConfiguration;
|
|
||||||
class MaemoSshRunner;
|
|
||||||
|
|
||||||
class MaemoDebugSupport : public RemoteLinux::AbstractRemoteLinuxDebugSupport
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
MaemoDebugSupport(MaemoRunConfiguration *runConfig, Debugger::DebuggerEngine *engine);
|
|
||||||
~MaemoDebugSupport();
|
|
||||||
|
|
||||||
private:
|
|
||||||
RemoteLinux::AbstractRemoteLinuxApplicationRunner *runner() const;
|
|
||||||
|
|
||||||
MaemoSshRunner * const m_runner;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace Madde
|
|
||||||
|
|
||||||
#endif // MAEMODEBUGSUPPORT_H
|
|
@@ -59,7 +59,7 @@ public:
|
|||||||
~MaemoRemoteMounter();
|
~MaemoRemoteMounter();
|
||||||
|
|
||||||
void setParameters(const ProjectExplorer::IDevice::ConstPtr &devConf,
|
void setParameters(const ProjectExplorer::IDevice::ConstPtr &devConf,
|
||||||
const Utils::FileName &fileName);
|
const Utils::FileName &maddeRoot);
|
||||||
void addMountSpecification(const MaemoMountSpecification &mountSpec,
|
void addMountSpecification(const MaemoMountSpecification &mountSpec,
|
||||||
bool mountAsRoot);
|
bool mountAsRoot);
|
||||||
bool hasValidMountSpecifications() const;
|
bool hasValidMountSpecifications() const;
|
||||||
|
@@ -135,32 +135,6 @@ Utils::PortList MaemoRunConfiguration::freePorts() const
|
|||||||
return MaemoGlobal::freePorts(target()->profile());
|
return MaemoGlobal::freePorts(target()->profile());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MaemoRunConfiguration::localDirToMountForRemoteGdb() const
|
|
||||||
{
|
|
||||||
const QString projectDir
|
|
||||||
= QDir::fromNativeSeparators(QDir::cleanPath(activeBuildConfiguration()
|
|
||||||
->target()->project()->projectDirectory()));
|
|
||||||
const QString execDir
|
|
||||||
= QDir::fromNativeSeparators(QFileInfo(localExecutableFilePath()).path());
|
|
||||||
const int length = qMin(projectDir.length(), execDir.length());
|
|
||||||
int lastSeparatorPos = 0;
|
|
||||||
for (int i = 0; i < length; ++i) {
|
|
||||||
if (projectDir.at(i) != execDir.at(i))
|
|
||||||
return projectDir.left(lastSeparatorPos);
|
|
||||||
if (projectDir.at(i) == QLatin1Char('/'))
|
|
||||||
lastSeparatorPos = i;
|
|
||||||
}
|
|
||||||
return projectDir.length() == execDir.length()
|
|
||||||
? projectDir : projectDir.left(lastSeparatorPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString MaemoRunConfiguration::remoteProjectSourcesMountPoint() const
|
|
||||||
{
|
|
||||||
return MaemoGlobal::homeDirOnDevice(DeviceProfileInformation::device(target()->profile())->sshParameters().userName)
|
|
||||||
+ QLatin1String("/gdbSourcesDir_")
|
|
||||||
+ QFileInfo(localExecutableFilePath()).fileName();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MaemoRunConfiguration::hasEnoughFreePorts(RunMode mode) const
|
bool MaemoRunConfiguration::hasEnoughFreePorts(RunMode mode) const
|
||||||
{
|
{
|
||||||
const int freePortCount = freePorts().count();
|
const int freePortCount = freePorts().count();
|
||||||
|
@@ -53,8 +53,6 @@ public:
|
|||||||
|
|
||||||
Internal::MaemoRemoteMountsModel *remoteMounts() const { return m_remoteMounts; }
|
Internal::MaemoRemoteMountsModel *remoteMounts() const { return m_remoteMounts; }
|
||||||
bool hasEnoughFreePorts(ProjectExplorer::RunMode mode) const;
|
bool hasEnoughFreePorts(ProjectExplorer::RunMode mode) const;
|
||||||
QString localDirToMountForRemoteGdb() const;
|
|
||||||
QString remoteProjectSourcesMountPoint() const;
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void remoteMountsChanged();
|
void remoteMountsChanged();
|
||||||
|
@@ -1,66 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator
|
|
||||||
**
|
|
||||||
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
|
||||||
**
|
|
||||||
** Contact: http://www.qt-project.org/
|
|
||||||
**
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
**
|
|
||||||
** 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, Nokia gives you certain additional
|
|
||||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
** Other Usage
|
|
||||||
**
|
|
||||||
** Alternatively, this file may be used in accordance with the terms and
|
|
||||||
** conditions contained in a signed written agreement between you and Nokia.
|
|
||||||
**
|
|
||||||
**
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "maemoruncontrol.h"
|
|
||||||
|
|
||||||
#include "maemoglobal.h"
|
|
||||||
#include "maemorunconfiguration.h"
|
|
||||||
#include "maemosshrunner.h"
|
|
||||||
|
|
||||||
namespace Madde {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
using namespace RemoteLinux;
|
|
||||||
using ProjectExplorer::RunConfiguration;
|
|
||||||
|
|
||||||
MaemoRunControl::MaemoRunControl(RunConfiguration *rc)
|
|
||||||
: AbstractRemoteLinuxRunControl(rc)
|
|
||||||
, m_runner(new MaemoSshRunner(this, qobject_cast<MaemoRunConfiguration *>(rc)))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MaemoRunControl::~MaemoRunControl()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaemoRunControl::start()
|
|
||||||
{
|
|
||||||
AbstractRemoteLinuxRunControl::start();
|
|
||||||
connect(m_runner, SIGNAL(mountDebugOutput(QString)), SLOT(handleMountDebugOutput(QString)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaemoRunControl::handleMountDebugOutput(const QString &output)
|
|
||||||
{
|
|
||||||
appendMessage(output, Utils::StdErrFormatSameLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRemoteLinuxApplicationRunner *MaemoRunControl::runner() const { return m_runner; }
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace Madde
|
|
@@ -1,64 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator
|
|
||||||
**
|
|
||||||
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
|
||||||
**
|
|
||||||
** Contact: http://www.qt-project.org/
|
|
||||||
**
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
**
|
|
||||||
** 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, Nokia gives you certain additional
|
|
||||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
** Other Usage
|
|
||||||
**
|
|
||||||
** Alternatively, this file may be used in accordance with the terms and
|
|
||||||
** conditions contained in a signed written agreement between you and Nokia.
|
|
||||||
**
|
|
||||||
**
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef MAEMORUNCONTROL_H
|
|
||||||
#define MAEMORUNCONTROL_H
|
|
||||||
|
|
||||||
#include <remotelinux/remotelinuxruncontrol.h>
|
|
||||||
|
|
||||||
namespace RemoteLinux {
|
|
||||||
class RemoteLinuxRunConfiguration;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Madde {
|
|
||||||
namespace Internal {
|
|
||||||
class MaemoSshRunner;
|
|
||||||
|
|
||||||
class MaemoRunControl : public RemoteLinux::AbstractRemoteLinuxRunControl
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit MaemoRunControl(ProjectExplorer::RunConfiguration *runConfig);
|
|
||||||
virtual ~MaemoRunControl();
|
|
||||||
|
|
||||||
void start();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void handleMountDebugOutput(const QString &output);
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual RemoteLinux::AbstractRemoteLinuxApplicationRunner *runner() const;
|
|
||||||
|
|
||||||
MaemoSshRunner * const m_runner;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace Madde
|
|
||||||
|
|
||||||
#endif // MAEMORUNCONTROL_H
|
|
@@ -28,11 +28,11 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
#include "maemorunfactories.h"
|
#include "maemorunfactories.h"
|
||||||
|
|
||||||
|
#include "maemoapplicationrunnerhelperactions.h"
|
||||||
#include "maemoconstants.h"
|
#include "maemoconstants.h"
|
||||||
#include "maemodebugsupport.h"
|
#include "maemoglobal.h"
|
||||||
#include "maemoremotemountsmodel.h"
|
#include "maemoremotemountsmodel.h"
|
||||||
#include "maemorunconfiguration.h"
|
#include "maemorunconfiguration.h"
|
||||||
#include "maemoruncontrol.h"
|
|
||||||
|
|
||||||
#include <debugger/debuggerconstants.h>
|
#include <debugger/debuggerconstants.h>
|
||||||
#include <debugger/debuggerstartparameters.h>
|
#include <debugger/debuggerstartparameters.h>
|
||||||
@@ -44,6 +44,8 @@
|
|||||||
#include <qt4projectmanager/qt4nodes.h>
|
#include <qt4projectmanager/qt4nodes.h>
|
||||||
#include <qt4projectmanager/qt4project.h>
|
#include <qt4projectmanager/qt4project.h>
|
||||||
#include <qtsupport/customexecutablerunconfiguration.h>
|
#include <qtsupport/customexecutablerunconfiguration.h>
|
||||||
|
#include <remotelinux/remotelinuxdebugsupport.h>
|
||||||
|
#include <remotelinux/remotelinuxruncontrol.h>
|
||||||
|
|
||||||
using namespace Debugger;
|
using namespace Debugger;
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
@@ -169,7 +171,6 @@ QList<RunConfiguration *> MaemoRunConfigurationFactory::runConfigurationsForNode
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// #pragma mark -- MaemoRunControlFactory
|
|
||||||
|
|
||||||
MaemoRunControlFactory::MaemoRunControlFactory(QObject *parent)
|
MaemoRunControlFactory::MaemoRunControlFactory(QObject *parent)
|
||||||
: IRunControlFactory(parent)
|
: IRunControlFactory(parent)
|
||||||
@@ -197,14 +198,21 @@ RunControl* MaemoRunControlFactory::create(RunConfiguration *runConfig, RunMode
|
|||||||
Q_ASSERT(rc);
|
Q_ASSERT(rc);
|
||||||
|
|
||||||
if (mode == NormalRunMode)
|
if (mode == NormalRunMode)
|
||||||
return new MaemoRunControl(rc);
|
return new RemoteLinuxRunControl(rc);
|
||||||
|
|
||||||
const DebuggerStartParameters params
|
const DebuggerStartParameters params = LinuxDeviceDebugSupport::startParameters(rc);
|
||||||
= AbstractRemoteLinuxDebugSupport::startParameters(rc);
|
|
||||||
DebuggerRunControl * const runControl = DebuggerPlugin::createDebugger(params, rc);
|
DebuggerRunControl * const runControl = DebuggerPlugin::createDebugger(params, rc);
|
||||||
if (!runControl)
|
if (!runControl)
|
||||||
return 0;
|
return 0;
|
||||||
MaemoDebugSupport *debugSupport = new MaemoDebugSupport(rc, runControl->engine());
|
LinuxDeviceDebugSupport * const debugSupport
|
||||||
|
= new LinuxDeviceDebugSupport(rc, runControl->engine());
|
||||||
|
const Profile * const profile = runConfig->target()->profile();
|
||||||
|
MaemoPreRunAction * const preRunAction = new MaemoPreRunAction(
|
||||||
|
DeviceProfileInformation::device(profile), MaemoGlobal::maddeRoot(profile),
|
||||||
|
rc->remoteMounts()->mountSpecs(), rc);
|
||||||
|
MaemoPostRunAction * const postRunAction = new MaemoPostRunAction(preRunAction->mounter(), rc);
|
||||||
|
debugSupport->setApplicationRunnerPreRunAction(preRunAction);
|
||||||
|
debugSupport->setApplicationRunnerPostRunAction(postRunAction);
|
||||||
connect(runControl, SIGNAL(finished()), debugSupport, SLOT(handleDebuggingFinished()));
|
connect(runControl, SIGNAL(finished()), debugSupport, SLOT(handleDebuggingFinished()));
|
||||||
return runControl;
|
return runControl;
|
||||||
}
|
}
|
||||||
|
@@ -1,215 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator
|
|
||||||
**
|
|
||||||
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
|
||||||
**
|
|
||||||
** Contact: http://www.qt-project.org/
|
|
||||||
**
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
**
|
|
||||||
** 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, Nokia gives you certain additional
|
|
||||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
** Other Usage
|
|
||||||
**
|
|
||||||
** Alternatively, this file may be used in accordance with the terms and
|
|
||||||
** conditions contained in a signed written agreement between you and Nokia.
|
|
||||||
**
|
|
||||||
**
|
|
||||||
**************************************************************************/
|
|
||||||
#include "maemosshrunner.h"
|
|
||||||
|
|
||||||
#include "maemoglobal.h"
|
|
||||||
#include "maemoqemumanager.h"
|
|
||||||
#include "maemoremotemounter.h"
|
|
||||||
#include "maemoremotemountsmodel.h"
|
|
||||||
#include "maemorunconfiguration.h"
|
|
||||||
|
|
||||||
#include <projectexplorer/buildconfiguration.h>
|
|
||||||
#include <projectexplorer/target.h>
|
|
||||||
#include <qtsupport/qtprofileinformation.h>
|
|
||||||
#include <utils/qtcassert.h>
|
|
||||||
#include <ssh/sshconnection.h>
|
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
|
||||||
using namespace QSsh;
|
|
||||||
using namespace RemoteLinux;
|
|
||||||
|
|
||||||
namespace Madde {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
MaemoSshRunner::MaemoSshRunner(QObject *parent, MaemoRunConfiguration *runConfig)
|
|
||||||
: AbstractRemoteLinuxApplicationRunner(runConfig, parent),
|
|
||||||
m_mounter(new MaemoRemoteMounter(this)),
|
|
||||||
m_mountSpecs(runConfig->remoteMounts()->mountSpecs()),
|
|
||||||
m_mountState(InactiveMountState)
|
|
||||||
{
|
|
||||||
const BuildConfiguration * const bc = runConfig->target()->activeBuildConfiguration();
|
|
||||||
Profile *profile = bc ? bc->target()->profile() : 0;
|
|
||||||
m_qtId = QtSupport::QtProfileInformation::qtVersionId(profile);
|
|
||||||
m_mounter->setParameters(devConfig(), MaemoGlobal::maddeRoot(profile));
|
|
||||||
connect(m_mounter, SIGNAL(mounted()), this, SLOT(handleMounted()));
|
|
||||||
connect(m_mounter, SIGNAL(unmounted()), this, SLOT(handleUnmounted()));
|
|
||||||
connect(m_mounter, SIGNAL(error(QString)), this,
|
|
||||||
SLOT(handleMounterError(QString)));
|
|
||||||
connect(m_mounter, SIGNAL(reportProgress(QString)), this,
|
|
||||||
SIGNAL(reportProgress(QString)));
|
|
||||||
connect(m_mounter, SIGNAL(debugOutput(QString)), this,
|
|
||||||
SIGNAL(mountDebugOutput(QString)));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MaemoSshRunner::canRun(QString &whyNot) const
|
|
||||||
{
|
|
||||||
if (!AbstractRemoteLinuxApplicationRunner::canRun(whyNot))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (devConfig()->machineType() == IDevice::Emulator
|
|
||||||
&& !MaemoQemuManager::instance().qemuIsRunning()) {
|
|
||||||
MaemoQemuRuntime rt;
|
|
||||||
if (MaemoQemuManager::instance().runtimeForQtVersion(m_qtId, &rt)) {
|
|
||||||
MaemoQemuManager::instance().startRuntime();
|
|
||||||
whyNot = tr("Qemu was not running. It has now been started up for you, but it will "
|
|
||||||
"take a bit of time until it is ready. Please try again then.");
|
|
||||||
} else {
|
|
||||||
whyNot = tr("You want to run on Qemu, but it is not enabled for this Qt version.");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaemoSshRunner::doDeviceSetup()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_mountState == InactiveMountState, return);
|
|
||||||
|
|
||||||
handleDeviceSetupDone(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaemoSshRunner::doAdditionalInitialCleanup()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_mountState == InactiveMountState, return);
|
|
||||||
|
|
||||||
m_mounter->resetMountSpecifications();
|
|
||||||
for (int i = 0; i < m_mountSpecs.count(); ++i)
|
|
||||||
m_mounter->addMountSpecification(m_mountSpecs.at(i), false);
|
|
||||||
m_mountState = InitialUnmounting;
|
|
||||||
unmount();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaemoSshRunner::doAdditionalInitializations()
|
|
||||||
{
|
|
||||||
mount();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaemoSshRunner::doPostRunCleanup()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_mountState == Mounted, return);
|
|
||||||
|
|
||||||
m_mountState = PostRunUnmounting;
|
|
||||||
unmount();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaemoSshRunner::handleUnmounted()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_mountState == InitialUnmounting || m_mountState == PostRunUnmounting, return);
|
|
||||||
|
|
||||||
switch (m_mountState) {
|
|
||||||
case InitialUnmounting:
|
|
||||||
m_mountState = InactiveMountState;
|
|
||||||
handleInitialCleanupDone(true);
|
|
||||||
break;
|
|
||||||
case PostRunUnmounting:
|
|
||||||
m_mountState = InactiveMountState;
|
|
||||||
handlePostRunCleanupDone();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
m_mountState = InactiveMountState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaemoSshRunner::doAdditionalConnectionErrorHandling()
|
|
||||||
{
|
|
||||||
m_mountState = InactiveMountState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaemoSshRunner::handleMounted()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_mountState == Mounting, return);
|
|
||||||
|
|
||||||
if (m_mountState == Mounting) {
|
|
||||||
m_mountState = Mounted;
|
|
||||||
handleInitializationsDone(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaemoSshRunner::handleMounterError(const QString &errorMsg)
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_mountState == InitialUnmounting || m_mountState == Mounting
|
|
||||||
|| m_mountState == PostRunUnmounting, return);
|
|
||||||
|
|
||||||
const MountState oldMountState = m_mountState;
|
|
||||||
m_mountState = InactiveMountState;
|
|
||||||
emit error(errorMsg);
|
|
||||||
switch (oldMountState) {
|
|
||||||
case InitialUnmounting:
|
|
||||||
handleInitialCleanupDone(false);
|
|
||||||
break;
|
|
||||||
case Mounting:
|
|
||||||
handleInitializationsDone(false);
|
|
||||||
break;
|
|
||||||
case PostRunUnmounting:
|
|
||||||
handlePostRunCleanupDone();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaemoSshRunner::mount()
|
|
||||||
{
|
|
||||||
m_mountState = Mounting;
|
|
||||||
if (m_mounter->hasValidMountSpecifications()) {
|
|
||||||
emit reportProgress(tr("Mounting host directories..."));
|
|
||||||
m_mounter->mount();
|
|
||||||
} else {
|
|
||||||
handleMounted();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaemoSshRunner::unmount()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_mountState == InitialUnmounting || m_mountState == PostRunUnmounting, return);
|
|
||||||
|
|
||||||
if (m_mounter->hasValidMountSpecifications()) {
|
|
||||||
QString message;
|
|
||||||
switch (m_mountState) {
|
|
||||||
case InitialUnmounting:
|
|
||||||
message = tr("Potentially unmounting left-over host directory mounts...");
|
|
||||||
break;
|
|
||||||
case PostRunUnmounting:
|
|
||||||
message = tr("Unmounting host directories...");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
emit reportProgress(message);
|
|
||||||
m_mounter->unmount();
|
|
||||||
} else {
|
|
||||||
handleUnmounted();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace Madde
|
|
||||||
|
|
@@ -0,0 +1,339 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: http://www.qt-project.org/
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
**
|
||||||
|
** 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, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** Other Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used in accordance with the terms and
|
||||||
|
** conditions contained in a signed written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#include "deviceapplicationrunner.h"
|
||||||
|
|
||||||
|
#include <ssh/sshconnection.h>
|
||||||
|
#include <ssh/sshconnectionmanager.h>
|
||||||
|
#include <ssh/sshremoteprocess.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
using namespace QSsh;
|
||||||
|
|
||||||
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
enum State { Inactive, Connecting, PreRun, Run, PostRun };
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
class DeviceApplicationRunner::DeviceApplicationRunnerPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SshConnection *connection;
|
||||||
|
DeviceApplicationHelperAction *preRunAction;
|
||||||
|
DeviceApplicationHelperAction *postRunAction;
|
||||||
|
IDevice::ConstPtr device;
|
||||||
|
SshRemoteProcess::Ptr remoteApp;
|
||||||
|
QTimer stopTimer;
|
||||||
|
QByteArray commandLine;
|
||||||
|
State state;
|
||||||
|
bool stopRequested;
|
||||||
|
bool success;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
DeviceApplicationHelperAction::DeviceApplicationHelperAction(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceApplicationHelperAction::~DeviceApplicationHelperAction()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DeviceApplicationRunner::DeviceApplicationRunner(QObject *parent) :
|
||||||
|
QObject(parent), d(new DeviceApplicationRunnerPrivate)
|
||||||
|
{
|
||||||
|
d->preRunAction = 0;
|
||||||
|
d->postRunAction = 0;
|
||||||
|
d->connection = 0;
|
||||||
|
d->state = Inactive;
|
||||||
|
|
||||||
|
d->stopTimer.setSingleShot(true);
|
||||||
|
connect(&d->stopTimer, SIGNAL(timeout()), SLOT(handleStopTimeout()));
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceApplicationRunner::~DeviceApplicationRunner()
|
||||||
|
{
|
||||||
|
setFinished();
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::start(const IDevice::ConstPtr &device,
|
||||||
|
const QByteArray &commandLine)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->state == Inactive, return);
|
||||||
|
|
||||||
|
d->device = device;
|
||||||
|
d->commandLine = commandLine;
|
||||||
|
d->stopRequested = false;
|
||||||
|
d->success = true;
|
||||||
|
|
||||||
|
connectToServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::stop(const QByteArray &stopCommand)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->state != Inactive, return);
|
||||||
|
|
||||||
|
if (d->stopRequested)
|
||||||
|
return;
|
||||||
|
d->stopRequested = true;
|
||||||
|
d->success = false;
|
||||||
|
emit reportProgress(tr("User requested stop. Shutting down..."));
|
||||||
|
switch (d->state) {
|
||||||
|
case Connecting:
|
||||||
|
setFinished();
|
||||||
|
break;
|
||||||
|
case PreRun:
|
||||||
|
d->preRunAction->stop();
|
||||||
|
break;
|
||||||
|
case Run:
|
||||||
|
d->stopTimer.start(10000);
|
||||||
|
d->connection->createRemoteProcess(stopCommand)->start();
|
||||||
|
break;
|
||||||
|
case PostRun:
|
||||||
|
d->postRunAction->stop();
|
||||||
|
break;
|
||||||
|
case Inactive:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::setPreRunAction(DeviceApplicationHelperAction *action)
|
||||||
|
{
|
||||||
|
addAction(d->preRunAction, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::setPostRunAction(DeviceApplicationHelperAction *action)
|
||||||
|
{
|
||||||
|
addAction(d->postRunAction, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::connectToServer()
|
||||||
|
{
|
||||||
|
QTC_CHECK(!d->connection);
|
||||||
|
|
||||||
|
d->state = Connecting;
|
||||||
|
|
||||||
|
if (!d->device) {
|
||||||
|
emit reportError(tr("Cannot run: No device."));
|
||||||
|
setFinished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->connection = SshConnectionManager::instance().acquireConnection(d->device->sshParameters());
|
||||||
|
connect(d->connection, SIGNAL(error(QSsh::SshError)), SLOT(handleConnectionFailure()));
|
||||||
|
if (d->connection->state() == SshConnection::Connected) {
|
||||||
|
handleConnected();
|
||||||
|
} else {
|
||||||
|
emit reportProgress(tr("Connecting to device..."));
|
||||||
|
connect(d->connection, SIGNAL(connected()), SLOT(handleConnected()));
|
||||||
|
if (d->connection->state() == QSsh::SshConnection::Unconnected)
|
||||||
|
d->connection->connectToHost();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::executePreRunAction()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->state == Connecting, return);
|
||||||
|
|
||||||
|
d->state = PreRun;
|
||||||
|
if (d->preRunAction)
|
||||||
|
d->preRunAction->start();
|
||||||
|
else
|
||||||
|
runApplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::executePostRunAction()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->state == PreRun || d->state == Run, return);
|
||||||
|
|
||||||
|
d->state = PostRun;
|
||||||
|
if (d->postRunAction)
|
||||||
|
d->postRunAction->start();
|
||||||
|
else
|
||||||
|
setFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::setFinished()
|
||||||
|
{
|
||||||
|
if (d->state == Inactive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (d->remoteApp) {
|
||||||
|
d->remoteApp->disconnect(this);
|
||||||
|
d->remoteApp->close();
|
||||||
|
d->remoteApp.clear();
|
||||||
|
}
|
||||||
|
if (d->connection) {
|
||||||
|
d->connection->disconnect(this);
|
||||||
|
SshConnectionManager::instance().releaseConnection(d->connection);
|
||||||
|
d->connection = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->state = Inactive;
|
||||||
|
emit finished(d->success);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::handleConnected()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->state == Connecting, return);
|
||||||
|
|
||||||
|
if (d->stopRequested) {
|
||||||
|
setFinished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
executePreRunAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::handleConnectionFailure()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->state != Inactive, return);
|
||||||
|
|
||||||
|
emit reportError(tr("SSH connection failed: %1").arg(d->connection->errorString()));
|
||||||
|
d->success = false;
|
||||||
|
switch (d->state) {
|
||||||
|
case Inactive:
|
||||||
|
break; // Can't happen.
|
||||||
|
case Connecting:
|
||||||
|
setFinished();
|
||||||
|
break;
|
||||||
|
case PreRun:
|
||||||
|
d->preRunAction->stop();
|
||||||
|
break;
|
||||||
|
case Run:
|
||||||
|
d->stopTimer.stop();
|
||||||
|
d->remoteApp->disconnect(this);
|
||||||
|
executePostRunAction();
|
||||||
|
break;
|
||||||
|
case PostRun:
|
||||||
|
d->postRunAction->stop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::handleHelperActionFinished(bool success)
|
||||||
|
{
|
||||||
|
switch (d->state) {
|
||||||
|
case Inactive:
|
||||||
|
break;
|
||||||
|
case PreRun:
|
||||||
|
if (success && d->success) {
|
||||||
|
runApplication();
|
||||||
|
} else if (success && !d->success) {
|
||||||
|
executePostRunAction();
|
||||||
|
} else {
|
||||||
|
d->success = false;
|
||||||
|
setFinished();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PostRun:
|
||||||
|
if (!success)
|
||||||
|
d->success = false;
|
||||||
|
setFinished();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
QTC_CHECK(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::addAction(DeviceApplicationHelperAction *&target,
|
||||||
|
DeviceApplicationHelperAction *source)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->state == Inactive, return);
|
||||||
|
|
||||||
|
if (target)
|
||||||
|
disconnect(target, 0, this, 0);
|
||||||
|
target = source;
|
||||||
|
if (target) {
|
||||||
|
connect(target, SIGNAL(finished(bool)), SLOT(handleHelperActionFinished(bool)));
|
||||||
|
connect(target, SIGNAL(reportProgress(QString)), SIGNAL(reportProgress(QString)));
|
||||||
|
connect(target, SIGNAL(reportError(QString)), SIGNAL(reportError(QString)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::handleStopTimeout()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->stopRequested && d->state == Run, return);
|
||||||
|
|
||||||
|
emit reportError(tr("Application did not finish in time, aborting."));
|
||||||
|
d->success = false;
|
||||||
|
setFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::handleApplicationFinished(int exitStatus)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->state == Run, return);
|
||||||
|
|
||||||
|
d->stopTimer.stop();
|
||||||
|
if (exitStatus == SshRemoteProcess::CrashExit) {
|
||||||
|
emit reportError(tr("Remote application crashed: %1").arg(d->remoteApp->errorString()));
|
||||||
|
d->success = false;
|
||||||
|
} else {
|
||||||
|
const int exitCode = d->remoteApp->exitCode();
|
||||||
|
if (exitCode != 0) {
|
||||||
|
emit reportError(tr("Remote application finished with exit code %1.").arg(exitCode));
|
||||||
|
d->success = false;
|
||||||
|
} else {
|
||||||
|
emit reportProgress(tr("Remote application finished with exit code 0."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
executePostRunAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::handleRemoteStdout()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->state == Run, return);
|
||||||
|
emit remoteStdout(d->remoteApp->readAllStandardOutput());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::handleRemoteStderr()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->state == Run, return);
|
||||||
|
emit remoteStderr(d->remoteApp->readAllStandardError());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceApplicationRunner::runApplication()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->state == PreRun, return);
|
||||||
|
|
||||||
|
d->state = Run;
|
||||||
|
d->remoteApp = d->connection->createRemoteProcess(d->commandLine);
|
||||||
|
connect(d->remoteApp.data(), SIGNAL(started()), SIGNAL(remoteProcessStarted()));
|
||||||
|
connect(d->remoteApp.data(), SIGNAL(readyReadStandardOutput()), SLOT(handleRemoteStdout()));
|
||||||
|
connect(d->remoteApp.data(), SIGNAL(readyReadStandardError()), SLOT(handleRemoteStderr()));
|
||||||
|
connect(d->remoteApp.data(), SIGNAL(closed(int)), SLOT(handleApplicationFinished(int)));
|
||||||
|
d->remoteApp->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ProjectExplorer
|
@@ -0,0 +1,104 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: http://www.qt-project.org/
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
**
|
||||||
|
** 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, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** Other Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used in accordance with the terms and
|
||||||
|
** conditions contained in a signed written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#ifndef ONDEVICEAPPLICATIONRUNNER_H
|
||||||
|
#define ONDEVICEAPPLICATIONRUNNER_H
|
||||||
|
|
||||||
|
#include "idevice.h"
|
||||||
|
|
||||||
|
#include "../projectexplorer_export.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
|
class PROJECTEXPLORER_EXPORT DeviceApplicationHelperAction : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
~DeviceApplicationHelperAction();
|
||||||
|
virtual void start() = 0;
|
||||||
|
virtual void stop() = 0;
|
||||||
|
signals:
|
||||||
|
void reportProgress(const QString &progressOutput);
|
||||||
|
void reportError(const QString &errorOutput);
|
||||||
|
void finished(bool success);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DeviceApplicationHelperAction(QObject *parent = 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
class PROJECTEXPLORER_EXPORT DeviceApplicationRunner : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DeviceApplicationRunner(QObject *parent = 0);
|
||||||
|
virtual ~DeviceApplicationRunner();
|
||||||
|
|
||||||
|
void start(const IDevice::ConstPtr &device, const QByteArray &commandLine);
|
||||||
|
void stop(const QByteArray &stopCommand);
|
||||||
|
|
||||||
|
// Use these if you need to do something before and after the application is run, respectively.
|
||||||
|
// Typically, the post-run action reverts the effects of the pre-run action.
|
||||||
|
// If you only have a pre-run action, you probably want a deploy step instead.
|
||||||
|
void setPreRunAction(DeviceApplicationHelperAction *action);
|
||||||
|
void setPostRunAction(DeviceApplicationHelperAction *action);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void remoteStdout(const QByteArray &output);
|
||||||
|
void remoteStderr(const QByteArray &output);
|
||||||
|
void reportProgress(const QString &progressOutput);
|
||||||
|
void reportError(const QString &errorOutput);
|
||||||
|
void remoteProcessStarted();
|
||||||
|
void finished(bool success);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleConnected();
|
||||||
|
void handleConnectionFailure();
|
||||||
|
void handleHelperActionFinished(bool success);
|
||||||
|
void handleStopTimeout();
|
||||||
|
void handleApplicationFinished(int exitStatus);
|
||||||
|
void handleRemoteStdout();
|
||||||
|
void handleRemoteStderr();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addAction(DeviceApplicationHelperAction *&target, DeviceApplicationHelperAction *source);
|
||||||
|
void connectToServer();
|
||||||
|
void executePreRunAction();
|
||||||
|
void executePostRunAction();
|
||||||
|
void runApplication();
|
||||||
|
void setFinished();
|
||||||
|
|
||||||
|
class DeviceApplicationRunnerPrivate;
|
||||||
|
DeviceApplicationRunnerPrivate * const d;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ProjectExplorer
|
||||||
|
|
||||||
|
#endif // ONDEVICEAPPLICATIONRUNNER_H
|
@@ -125,7 +125,8 @@ HEADERS += projectexplorer.h \
|
|||||||
devicesupport/deviceprocessesdialog.h \
|
devicesupport/deviceprocessesdialog.h \
|
||||||
devicesupport/devicesettingswidget.h \
|
devicesupport/devicesettingswidget.h \
|
||||||
devicesupport/devicesettingspage.h \
|
devicesupport/devicesettingspage.h \
|
||||||
devicesupport/deviceusedportsgatherer.h
|
devicesupport/deviceusedportsgatherer.h \
|
||||||
|
devicesupport/deviceapplicationrunner.h
|
||||||
|
|
||||||
SOURCES += projectexplorer.cpp \
|
SOURCES += projectexplorer.cpp \
|
||||||
abi.cpp \
|
abi.cpp \
|
||||||
@@ -227,7 +228,8 @@ SOURCES += projectexplorer.cpp \
|
|||||||
devicesupport/deviceprocessesdialog.cpp \
|
devicesupport/deviceprocessesdialog.cpp \
|
||||||
devicesupport/devicesettingswidget.cpp \
|
devicesupport/devicesettingswidget.cpp \
|
||||||
devicesupport/devicesettingspage.cpp \
|
devicesupport/devicesettingspage.cpp \
|
||||||
devicesupport/deviceusedportsgatherer.cpp
|
devicesupport/deviceusedportsgatherer.cpp \
|
||||||
|
devicesupport/deviceapplicationrunner.cpp
|
||||||
|
|
||||||
FORMS += processstep.ui \
|
FORMS += processstep.ui \
|
||||||
editorsettingspropertiespage.ui \
|
editorsettingspropertiespage.ui \
|
||||||
|
@@ -308,7 +308,9 @@ QtcPlugin {
|
|||||||
"devicesupport/deviceusedportsgatherer.h",
|
"devicesupport/deviceusedportsgatherer.h",
|
||||||
"devicesupport/idevicewidget.h",
|
"devicesupport/idevicewidget.h",
|
||||||
"devicesupport/idevicefactory.cpp",
|
"devicesupport/idevicefactory.cpp",
|
||||||
"devicesupport/idevicefactory.h"
|
"devicesupport/idevicefactory.h",
|
||||||
|
"devicesupport/deviceapplicationrunner.cpp",
|
||||||
|
"devicesupport/deviceapplicationrunner.h"
|
||||||
]
|
]
|
||||||
|
|
||||||
Group {
|
Group {
|
||||||
|
@@ -45,6 +45,7 @@
|
|||||||
#include <qt4projectmanager/qt-s60/s60devicedebugruncontrol.h>
|
#include <qt4projectmanager/qt-s60/s60devicedebugruncontrol.h>
|
||||||
#include <qt4projectmanager/qt-s60/s60devicerunconfiguration.h>
|
#include <qt4projectmanager/qt-s60/s60devicerunconfiguration.h>
|
||||||
#include <qmldebug/qmloutputparser.h>
|
#include <qmldebug/qmloutputparser.h>
|
||||||
|
#include <remotelinux/remotelinuxrunconfiguration.h>
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
@@ -370,6 +371,7 @@ void QmlProfilerEngine::profilerStateChanged()
|
|||||||
case QmlProfilerStateManager::Idle : {
|
case QmlProfilerStateManager::Idle : {
|
||||||
// When all the profiling is done, delete the profiler runner
|
// When all the profiling is done, delete the profiler runner
|
||||||
// (a new one will be created at start)
|
// (a new one will be created at start)
|
||||||
|
d->m_noDebugOutputTimer.stop();
|
||||||
if (d->m_runner) {
|
if (d->m_runner) {
|
||||||
delete d->m_runner;
|
delete d->m_runner;
|
||||||
d->m_runner = 0;
|
d->m_runner = 0;
|
||||||
|
@@ -27,15 +27,18 @@
|
|||||||
**
|
**
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "remotelinuxqmlprofilerrunner.h"
|
#include "remotelinuxqmlprofilerrunner.h"
|
||||||
#include <extensionsystem/pluginmanager.h>
|
|
||||||
|
#include <projectexplorer/devicesupport/deviceapplicationrunner.h>
|
||||||
|
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
|
||||||
|
#include <projectexplorer/profileinformation.h>
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
#include <remotelinux/remotelinuxapplicationrunner.h>
|
#include <projectexplorer/target.h>
|
||||||
|
#include <remotelinux/remotelinuxrunconfiguration.h>
|
||||||
|
#include <remotelinux/remotelinuxutils.h>
|
||||||
#include <utils/portlist.h>
|
#include <utils/portlist.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
using namespace ExtensionSystem;
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
using namespace QmlProfiler::Internal;
|
using namespace QmlProfiler::Internal;
|
||||||
using namespace RemoteLinux;
|
using namespace RemoteLinux;
|
||||||
@@ -43,55 +46,43 @@ using namespace RemoteLinux;
|
|||||||
RemoteLinuxQmlProfilerRunner::RemoteLinuxQmlProfilerRunner(
|
RemoteLinuxQmlProfilerRunner::RemoteLinuxQmlProfilerRunner(
|
||||||
RemoteLinuxRunConfiguration *runConfiguration, QObject *parent)
|
RemoteLinuxRunConfiguration *runConfiguration, QObject *parent)
|
||||||
: AbstractQmlProfilerRunner(parent)
|
: AbstractQmlProfilerRunner(parent)
|
||||||
|
, m_portsGatherer(new DeviceUsedPortsGatherer(this))
|
||||||
|
, m_runner(new DeviceApplicationRunner(this))
|
||||||
|
, m_device(DeviceProfileInformation::device(runConfiguration->target()->profile()))
|
||||||
|
, m_remoteExecutable(runConfiguration->remoteExecutableFilePath())
|
||||||
|
, m_arguments(runConfiguration->arguments())
|
||||||
|
, m_commandPrefix(runConfiguration->commandPrefix())
|
||||||
, m_port(0)
|
, m_port(0)
|
||||||
, m_runControl(0)
|
|
||||||
{
|
{
|
||||||
// find run control factory
|
connect(m_runner, SIGNAL(reportError(QString)), this, SLOT(handleError(QString)));
|
||||||
IRunControlFactory *runControlFactory = 0;
|
connect(m_runner, SIGNAL(remoteStderr(QByteArray)), this, SLOT(handleStdErr(QByteArray)));
|
||||||
QList<IRunControlFactory*> runControlFactories
|
connect(m_runner, SIGNAL(remoteStdout(QByteArray)), this, SLOT(handleStdOut(QByteArray)));
|
||||||
= PluginManager::getObjects<IRunControlFactory>();
|
connect(m_runner, SIGNAL(finished(bool)), SLOT(handleRemoteProcessFinished(bool)));
|
||||||
|
connect(m_runner, SIGNAL(reportProgress(QString)), this, SLOT(handleProgressReport(QString)));
|
||||||
foreach (IRunControlFactory *factory, runControlFactories) {
|
connect(m_portsGatherer, SIGNAL(error(QString)), SLOT(handlePortsGathererError(QString)));
|
||||||
if (factory->canRun(runConfiguration, NormalRunMode)) {
|
connect(m_portsGatherer, SIGNAL(portListReady()), SLOT(handlePortListReady()));
|
||||||
runControlFactory = factory;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QTC_ASSERT(runControlFactory, return);
|
|
||||||
|
|
||||||
// create run control
|
|
||||||
RunControl *runControl = runControlFactory->create(runConfiguration, NormalRunMode);
|
|
||||||
|
|
||||||
m_runControl = qobject_cast<AbstractRemoteLinuxRunControl*>(runControl);
|
|
||||||
QTC_ASSERT(m_runControl, return);
|
|
||||||
|
|
||||||
connect(runner(), SIGNAL(readyForExecution()), this, SLOT(getPorts()));
|
|
||||||
connect(runner(), SIGNAL(error(QString)), this, SLOT(handleError(QString)));
|
|
||||||
connect(runner(), SIGNAL(remoteErrorOutput(QByteArray)), this, SLOT(handleStdErr(QByteArray)));
|
|
||||||
connect(runner(), SIGNAL(remoteOutput(QByteArray)), this, SLOT(handleStdOut(QByteArray)));
|
|
||||||
|
|
||||||
connect(runner(), SIGNAL(remoteProcessStarted()), this, SLOT(handleRemoteProcessStarted()));
|
|
||||||
connect(runner(), SIGNAL(remoteProcessFinished(qint64)),
|
|
||||||
this, SLOT(handleRemoteProcessFinished(qint64)));
|
|
||||||
connect(runner(), SIGNAL(reportProgress(QString)), this, SLOT(handleProgressReport(QString)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteLinuxQmlProfilerRunner::~RemoteLinuxQmlProfilerRunner()
|
RemoteLinuxQmlProfilerRunner::~RemoteLinuxQmlProfilerRunner()
|
||||||
{
|
{
|
||||||
delete m_runControl;
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteLinuxQmlProfilerRunner::start()
|
void RemoteLinuxQmlProfilerRunner::start()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(runner(), return);
|
QTC_ASSERT(m_port == 0, return);
|
||||||
runner()->start();
|
|
||||||
|
m_portsGatherer->start(m_device);
|
||||||
|
emit started();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteLinuxQmlProfilerRunner::stop()
|
void RemoteLinuxQmlProfilerRunner::stop()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(runner(), return);
|
if (m_port == 0)
|
||||||
runner()->stop();
|
m_portsGatherer->stop();
|
||||||
|
else
|
||||||
|
m_runner->stop(RemoteLinuxUtils::killApplicationCommandLine(m_remoteExecutable).toUtf8());
|
||||||
|
m_port = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
quint16 RemoteLinuxQmlProfilerRunner::debugPort() const
|
quint16 RemoteLinuxQmlProfilerRunner::debugPort() const
|
||||||
@@ -99,26 +90,37 @@ quint16 RemoteLinuxQmlProfilerRunner::debugPort() const
|
|||||||
return m_port;
|
return m_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemoteLinuxQmlProfilerRunner::handlePortsGathererError(const QString &message)
|
||||||
|
{
|
||||||
|
emit appendMessage(tr("Gathering ports failed: %1").arg(message), Utils::ErrorMessageFormat);
|
||||||
|
m_port = 0;
|
||||||
|
emit stopped();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteLinuxQmlProfilerRunner::handlePortListReady()
|
||||||
|
{
|
||||||
|
getPorts();
|
||||||
|
}
|
||||||
|
|
||||||
void RemoteLinuxQmlProfilerRunner::getPorts()
|
void RemoteLinuxQmlProfilerRunner::getPorts()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(runner(), return);
|
Utils::PortList portList = m_device->freePorts();
|
||||||
m_port = runner()->freePorts()->getNext();
|
m_port = m_portsGatherer->getNextFreePort(&portList);
|
||||||
if (m_port == 0) {
|
|
||||||
|
if (m_port == -1) {
|
||||||
emit appendMessage(tr("Not enough free ports on device for analyzing.\n"),
|
emit appendMessage(tr("Not enough free ports on device for analyzing.\n"),
|
||||||
Utils::ErrorMessageFormat);
|
Utils::ErrorMessageFormat);
|
||||||
runner()->stop();
|
m_port = 0;
|
||||||
|
emit stopped();
|
||||||
} else {
|
} else {
|
||||||
emit appendMessage(tr("Starting remote process ...\n"), Utils::NormalMessageFormat);
|
emit appendMessage(tr("Starting remote process ...\n"), Utils::NormalMessageFormat);
|
||||||
|
QString arguments = m_arguments;
|
||||||
QString arguments = runner()->arguments();
|
|
||||||
if (!arguments.isEmpty())
|
if (!arguments.isEmpty())
|
||||||
arguments.append(QLatin1Char(' '));
|
arguments.append(QLatin1Char(' '));
|
||||||
arguments.append(QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(m_port));
|
arguments.append(QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(m_port));
|
||||||
|
const QString commandLine = QString::fromLatin1("%1 %2 %3")
|
||||||
runner()->startExecution(QString::fromLatin1("%1 %2 %3")
|
.arg(m_commandPrefix, m_remoteExecutable, arguments);
|
||||||
.arg(runner()->commandPrefix())
|
m_runner->start(m_device, commandLine.toUtf8());
|
||||||
.arg(runner()->remoteExecutable())
|
|
||||||
.arg(arguments).toUtf8());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,18 +139,11 @@ void RemoteLinuxQmlProfilerRunner::handleStdOut(const QByteArray &msg)
|
|||||||
emit appendMessage(QString::fromUtf8(msg), Utils::StdOutFormat);
|
emit appendMessage(QString::fromUtf8(msg), Utils::StdOutFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteLinuxQmlProfilerRunner::handleRemoteProcessStarted()
|
void RemoteLinuxQmlProfilerRunner::handleRemoteProcessFinished(bool success)
|
||||||
{
|
{
|
||||||
emit started();
|
if (!success)
|
||||||
}
|
appendMessage(tr("Failure running remote process."), Utils::NormalMessageFormat);
|
||||||
|
m_port = 0;
|
||||||
void RemoteLinuxQmlProfilerRunner::handleRemoteProcessFinished(qint64 exitCode)
|
|
||||||
{
|
|
||||||
if (exitCode != AbstractRemoteLinuxApplicationRunner::InvalidExitCode) {
|
|
||||||
appendMessage(tr("Finished running remote process. Exit code was %1.\n")
|
|
||||||
.arg(exitCode), Utils::NormalMessageFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit stopped();
|
emit stopped();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,11 +151,3 @@ void RemoteLinuxQmlProfilerRunner::handleProgressReport(const QString &progressS
|
|||||||
{
|
{
|
||||||
appendMessage(progressString + QLatin1Char('\n'), Utils::NormalMessageFormat);
|
appendMessage(progressString + QLatin1Char('\n'), Utils::NormalMessageFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractRemoteLinuxApplicationRunner *RemoteLinuxQmlProfilerRunner::runner() const
|
|
||||||
{
|
|
||||||
if (!m_runControl)
|
|
||||||
return 0;
|
|
||||||
return m_runControl->runner();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@@ -32,8 +32,16 @@
|
|||||||
#define REMOTELINUXQMLPROFILERRUNNER_H
|
#define REMOTELINUXQMLPROFILERRUNNER_H
|
||||||
|
|
||||||
#include "abstractqmlprofilerrunner.h"
|
#include "abstractqmlprofilerrunner.h"
|
||||||
#include <remotelinux/remotelinuxrunconfiguration.h>
|
|
||||||
#include <remotelinux/remotelinuxruncontrol.h>
|
#include <projectexplorer/devicesupport/idevice.h>
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace ProjectExplorer {
|
||||||
|
class DeviceApplicationRunner;
|
||||||
|
class DeviceUsedPortsGatherer;
|
||||||
|
}
|
||||||
|
namespace RemoteLinux { class RemoteLinuxRunConfiguration; }
|
||||||
|
|
||||||
namespace QmlProfiler {
|
namespace QmlProfiler {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -54,19 +62,24 @@ public:
|
|||||||
virtual quint16 debugPort() const;
|
virtual quint16 debugPort() const;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void getPorts();
|
|
||||||
void handleError(const QString &msg);
|
void handleError(const QString &msg);
|
||||||
void handleStdErr(const QByteArray &msg);
|
void handleStdErr(const QByteArray &msg);
|
||||||
void handleStdOut(const QByteArray &msg);
|
void handleStdOut(const QByteArray &msg);
|
||||||
void handleRemoteProcessStarted();
|
void handleRemoteProcessFinished(bool success);
|
||||||
void handleRemoteProcessFinished(qint64);
|
|
||||||
void handleProgressReport(const QString &progressString);
|
void handleProgressReport(const QString &progressString);
|
||||||
|
void handlePortsGathererError(const QString &message);
|
||||||
|
void handlePortListReady();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RemoteLinux::AbstractRemoteLinuxApplicationRunner *runner() const;
|
void getPorts();
|
||||||
|
|
||||||
quint16 m_port;
|
ProjectExplorer::DeviceUsedPortsGatherer * const m_portsGatherer;
|
||||||
RemoteLinux::AbstractRemoteLinuxRunControl *m_runControl;
|
ProjectExplorer::DeviceApplicationRunner * const m_runner;
|
||||||
|
const ProjectExplorer::IDevice::ConstPtr m_device;
|
||||||
|
const QString m_remoteExecutable;
|
||||||
|
const QString m_arguments;
|
||||||
|
const QString m_commandPrefix;
|
||||||
|
int m_port;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -41,7 +41,6 @@ SOURCES += qnxplugin.cpp \
|
|||||||
qnxrunconfiguration.cpp \
|
qnxrunconfiguration.cpp \
|
||||||
qnxruncontrolfactory.cpp \
|
qnxruncontrolfactory.cpp \
|
||||||
qnxdebugsupport.cpp \
|
qnxdebugsupport.cpp \
|
||||||
qnxapplicationrunner.cpp \
|
|
||||||
qnxdeploystepfactory.cpp \
|
qnxdeploystepfactory.cpp \
|
||||||
qnxdeployconfigurationfactory.cpp \
|
qnxdeployconfigurationfactory.cpp \
|
||||||
qnxrunconfigurationfactory.cpp \
|
qnxrunconfigurationfactory.cpp \
|
||||||
@@ -91,7 +90,6 @@ HEADERS += qnxplugin.h\
|
|||||||
qnxrunconfiguration.h \
|
qnxrunconfiguration.h \
|
||||||
qnxruncontrolfactory.h \
|
qnxruncontrolfactory.h \
|
||||||
qnxdebugsupport.h \
|
qnxdebugsupport.h \
|
||||||
qnxapplicationrunner.h \
|
|
||||||
qnxdeploystepfactory.h \
|
qnxdeploystepfactory.h \
|
||||||
qnxdeployconfigurationfactory.h \
|
qnxdeployconfigurationfactory.h \
|
||||||
qnxrunconfigurationfactory.h \
|
qnxrunconfigurationfactory.h \
|
||||||
|
@@ -1,85 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator
|
|
||||||
**
|
|
||||||
** Copyright (C) 2011 - 2012 Research In Motion
|
|
||||||
**
|
|
||||||
** Contact: Research In Motion (blackberry-qt@qnx.com)
|
|
||||||
** Contact: KDAB (info@kdab.com)
|
|
||||||
**
|
|
||||||
**
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
**
|
|
||||||
** 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, Nokia gives you certain additional
|
|
||||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
** Other Usage
|
|
||||||
**
|
|
||||||
** Alternatively, this file may be used in accordance with the terms and
|
|
||||||
** conditions contained in a signed written agreement between you and Nokia.
|
|
||||||
**
|
|
||||||
** If you have questions regarding the use of this file, please contact
|
|
||||||
** Nokia at info@qt.nokia.com.
|
|
||||||
**
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "qnxapplicationrunner.h"
|
|
||||||
#include "qnxrunconfiguration.h"
|
|
||||||
#include "qnxconstants.h"
|
|
||||||
|
|
||||||
using namespace Qnx;
|
|
||||||
using namespace Qnx::Internal;
|
|
||||||
|
|
||||||
QnxApplicationRunner::QnxApplicationRunner(QnxRunConfiguration *runConfig, QObject *parent)
|
|
||||||
: RemoteLinux::AbstractRemoteLinuxApplicationRunner(runConfig, parent)
|
|
||||||
, m_debugMode(false)
|
|
||||||
{
|
|
||||||
usedPortsGatherer()->setCommand(QLatin1String(Constants::QNX_PORT_GATHERER_COMMAND));
|
|
||||||
}
|
|
||||||
|
|
||||||
void QnxApplicationRunner::setDebugMode(bool debugMode)
|
|
||||||
{
|
|
||||||
m_debugMode = debugMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QnxApplicationRunner::doDeviceSetup()
|
|
||||||
{
|
|
||||||
handleDeviceSetupDone(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QnxApplicationRunner::doAdditionalInitialCleanup()
|
|
||||||
{
|
|
||||||
handleInitialCleanupDone(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QnxApplicationRunner::doAdditionalInitializations()
|
|
||||||
{
|
|
||||||
handleInitializationsDone(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QnxApplicationRunner::doPostRunCleanup()
|
|
||||||
{
|
|
||||||
handlePostRunCleanupDone();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QnxApplicationRunner::doAdditionalConnectionErrorHandling()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QnxApplicationRunner::killApplicationCommandLine() const
|
|
||||||
{
|
|
||||||
QString executable = m_debugMode ? QLatin1String(Constants::QNX_DEBUG_EXECUTABLE) : remoteExecutable();
|
|
||||||
executable.replace(QLatin1String("/"), QLatin1String("\\/"));
|
|
||||||
return QString::fromLatin1("for PID in $(ps -f -o pid,comm | grep %1 | awk '/%1/ {print $1}'); "
|
|
||||||
"do "
|
|
||||||
"kill $PID; sleep 1; kill -9 $PID; "
|
|
||||||
"done").arg(executable);
|
|
||||||
}
|
|
@@ -1,69 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator
|
|
||||||
**
|
|
||||||
** Copyright (C) 2011 - 2012 Research In Motion
|
|
||||||
**
|
|
||||||
** Contact: Research In Motion (blackberry-qt@qnx.com)
|
|
||||||
** Contact: KDAB (info@kdab.com)
|
|
||||||
**
|
|
||||||
**
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
**
|
|
||||||
** 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, Nokia gives you certain additional
|
|
||||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
** Other Usage
|
|
||||||
**
|
|
||||||
** Alternatively, this file may be used in accordance with the terms and
|
|
||||||
** conditions contained in a signed written agreement between you and Nokia.
|
|
||||||
**
|
|
||||||
** If you have questions regarding the use of this file, please contact
|
|
||||||
** Nokia at info@qt.nokia.com.
|
|
||||||
**
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef QNX_INTERNAL_QNXAPPLICATIONRUNNER_H
|
|
||||||
#define QNX_INTERNAL_QNXAPPLICATIONRUNNER_H
|
|
||||||
|
|
||||||
#include <remotelinux/remotelinuxapplicationrunner.h>
|
|
||||||
|
|
||||||
namespace Qnx {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class QnxRunConfiguration;
|
|
||||||
|
|
||||||
class QnxApplicationRunner : public RemoteLinux::AbstractRemoteLinuxApplicationRunner
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit QnxApplicationRunner(QnxRunConfiguration *runConfig,
|
|
||||||
QObject *parent = 0);
|
|
||||||
|
|
||||||
void setDebugMode(bool debugMode);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void doDeviceSetup();
|
|
||||||
void doAdditionalInitialCleanup();
|
|
||||||
void doAdditionalInitializations();
|
|
||||||
void doPostRunCleanup();
|
|
||||||
void doAdditionalConnectionErrorHandling();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString killApplicationCommandLine() const;
|
|
||||||
|
|
||||||
bool m_debugMode;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace Qnx
|
|
||||||
|
|
||||||
#endif // QNX_INTERNAL_QNXAPPLICATIONRUNNER_H
|
|
@@ -32,22 +32,46 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "qnxdebugsupport.h"
|
#include "qnxdebugsupport.h"
|
||||||
#include "qnxapplicationrunner.h"
|
|
||||||
#include "qnxconstants.h"
|
#include "qnxconstants.h"
|
||||||
|
#include "qnxrunconfiguration.h"
|
||||||
|
#include "qnxutils.h"
|
||||||
|
|
||||||
#include <debugger/debuggerengine.h>
|
#include <debugger/debuggerengine.h>
|
||||||
|
#include <projectexplorer/devicesupport/deviceapplicationrunner.h>
|
||||||
|
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
|
||||||
|
#include <projectexplorer/profileinformation.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
#include <utils/portlist.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
using namespace ProjectExplorer;
|
||||||
|
using namespace RemoteLinux;
|
||||||
|
|
||||||
|
using namespace Qnx;
|
||||||
using namespace Qnx::Internal;
|
using namespace Qnx::Internal;
|
||||||
|
|
||||||
QnxDebugSupport::QnxDebugSupport(QnxRunConfiguration *runConfig, Debugger::DebuggerEngine *engine)
|
QnxDebugSupport::QnxDebugSupport(QnxRunConfiguration *runConfig, Debugger::DebuggerEngine *engine)
|
||||||
: QObject(engine)
|
: QObject(engine)
|
||||||
|
, m_executable(QLatin1String(Constants::QNX_DEBUG_EXECUTABLE))
|
||||||
|
, m_commandPrefix(runConfig->commandPrefix())
|
||||||
|
, m_arguments(runConfig->arguments())
|
||||||
|
, m_device(DeviceProfileInformation::device(runConfig->target()->profile()))
|
||||||
, m_engine(engine)
|
, m_engine(engine)
|
||||||
, m_port(-1)
|
, m_port(-1)
|
||||||
, m_state(Inactive)
|
, m_state(Inactive)
|
||||||
{
|
{
|
||||||
m_runner = new QnxApplicationRunner(runConfig, this);
|
m_runner = new DeviceApplicationRunner(this);
|
||||||
m_runner->setDebugMode(true);
|
m_portsGatherer = new DeviceUsedPortsGatherer(this);
|
||||||
|
m_portsGatherer->setCommand(QLatin1String(Constants::QNX_PORT_GATHERER_COMMAND));
|
||||||
|
|
||||||
|
connect(m_portsGatherer, SIGNAL(error(QString)), SLOT(handleError(QString)));
|
||||||
|
connect(m_portsGatherer, SIGNAL(portListReady()), SLOT(handlePortListReady()));
|
||||||
|
|
||||||
|
connect(m_runner, SIGNAL(reportError(QString)), SLOT(handleError(QString)));
|
||||||
|
connect(m_runner, SIGNAL(remoteProcessStarted()), this, SLOT(handleRemoteProcessStarted()));
|
||||||
|
connect(m_runner, SIGNAL(finished(bool)), SLOT(handleRemoteProcessFinished(qint64)));
|
||||||
|
connect(m_runner, SIGNAL(reportProgress(QString)), this, SLOT(handleProgressReport(QString)));
|
||||||
|
connect(m_runner, SIGNAL(remoteStdout(QByteArray)), this, SLOT(handleRemoteOutput(QByteArray)));
|
||||||
|
|
||||||
connect(m_engine, SIGNAL(requestRemoteSetup()), this, SLOT(handleAdapterSetupRequested()));
|
connect(m_engine, SIGNAL(requestRemoteSetup()), this, SLOT(handleAdapterSetupRequested()));
|
||||||
}
|
}
|
||||||
@@ -56,18 +80,16 @@ void QnxDebugSupport::handleAdapterSetupRequested()
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(m_state == Inactive, return);
|
QTC_ASSERT(m_state == Inactive, return);
|
||||||
|
|
||||||
m_state = StartingRunner;
|
m_state = GatheringPorts;
|
||||||
if (m_engine)
|
if (m_engine)
|
||||||
m_engine->showMessage(tr("Preparing remote side...\n"), Debugger::AppStuff);
|
m_engine->showMessage(tr("Preparing remote side...\n"), Debugger::AppStuff);
|
||||||
|
m_portsGatherer->start(m_device);
|
||||||
|
}
|
||||||
|
|
||||||
connect(m_runner, SIGNAL(error(QString)), this, SLOT(handleSshError(QString)));
|
void QnxDebugSupport::handlePortListReady()
|
||||||
connect(m_runner, SIGNAL(readyForExecution()), this, SLOT(startExecution()));
|
{
|
||||||
connect(m_runner, SIGNAL(remoteProcessStarted()), this, SLOT(handleRemoteProcessStarted()));
|
QTC_ASSERT(m_state == GatheringPorts, return);
|
||||||
connect(m_runner, SIGNAL(remoteProcessFinished(qint64)), this, SLOT(handleRemoteProcessFinished(qint64)));
|
startExecution();
|
||||||
connect(m_runner, SIGNAL(reportProgress(QString)), this, SLOT(handleProgressReport(QString)));
|
|
||||||
connect(m_runner, SIGNAL(remoteOutput(QByteArray)), this, SLOT(handleRemoteOutput(QByteArray)));
|
|
||||||
|
|
||||||
m_runner->start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QnxDebugSupport::startExecution()
|
void QnxDebugSupport::startExecution()
|
||||||
@@ -75,13 +97,13 @@ void QnxDebugSupport::startExecution()
|
|||||||
if (m_state == Inactive)
|
if (m_state == Inactive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QTC_ASSERT(m_state == StartingRunner, return);
|
|
||||||
|
|
||||||
m_state = StartingRemoteProcess;
|
m_state = StartingRemoteProcess;
|
||||||
m_port = m_runner->usedPortsGatherer()->getNextFreePort(m_runner->freePorts());
|
Utils::PortList portList = m_device->freePorts();
|
||||||
|
m_port = m_portsGatherer->getNextFreePort(&portList);
|
||||||
|
|
||||||
const QString remoteCommandLine = QString::fromLatin1("%1 %2 %3").arg(m_runner->commandPrefix()).arg(QLatin1String(Constants::QNX_DEBUG_EXECUTABLE)).arg(m_port);
|
const QString remoteCommandLine = QString::fromLatin1("%1 %2 %3")
|
||||||
m_runner->startExecution(remoteCommandLine.toUtf8());
|
.arg(m_commandPrefix, m_executable).arg(m_port);
|
||||||
|
m_runner->start(m_device, remoteCommandLine.toUtf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QnxDebugSupport::handleRemoteProcessStarted()
|
void QnxDebugSupport::handleRemoteProcessStarted()
|
||||||
@@ -90,17 +112,17 @@ void QnxDebugSupport::handleRemoteProcessStarted()
|
|||||||
m_engine->notifyEngineRemoteSetupDone(m_port, -1);
|
m_engine->notifyEngineRemoteSetupDone(m_port, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QnxDebugSupport::handleRemoteProcessFinished(qint64 exitCode)
|
void QnxDebugSupport::handleRemoteProcessFinished(bool success)
|
||||||
{
|
{
|
||||||
if (m_engine || m_state == Inactive)
|
if (m_engine || m_state == Inactive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_state == Debugging) {
|
if (m_state == Debugging) {
|
||||||
if (exitCode != 0)
|
if (!success)
|
||||||
m_engine->notifyInferiorIll();
|
m_engine->notifyInferiorIll();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
const QString errorMsg = tr("The %1 process closed unexpectedly.").arg(QLatin1String(Constants::QNX_DEBUG_EXECUTABLE));
|
const QString errorMsg = tr("The %1 process closed unexpectedly.").arg(m_executable);
|
||||||
m_engine->notifyEngineRemoteSetupFailed(errorMsg);
|
m_engine->notifyEngineRemoteSetupFailed(errorMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,7 +135,7 @@ void QnxDebugSupport::handleDebuggingFinished()
|
|||||||
void QnxDebugSupport::setFinished()
|
void QnxDebugSupport::setFinished()
|
||||||
{
|
{
|
||||||
m_state = Inactive;
|
m_state = Inactive;
|
||||||
m_runner->stop();
|
m_runner->stop(QnxUtils::applicationKillCommand(m_executable).toUtf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QnxDebugSupport::handleProgressReport(const QString &progressOutput)
|
void QnxDebugSupport::handleProgressReport(const QString &progressOutput)
|
||||||
@@ -130,7 +152,7 @@ void QnxDebugSupport::handleRemoteOutput(const QByteArray &output)
|
|||||||
m_engine->showMessage(QString::fromUtf8(output), Debugger::AppOutput);
|
m_engine->showMessage(QString::fromUtf8(output), Debugger::AppOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QnxDebugSupport::handleSshError(const QString &error)
|
void QnxDebugSupport::handleError(const QString &error)
|
||||||
{
|
{
|
||||||
if (m_state == Debugging) {
|
if (m_state == Debugging) {
|
||||||
if (m_engine) {
|
if (m_engine) {
|
||||||
|
@@ -34,16 +34,20 @@
|
|||||||
#ifndef QNX_INTERNAL_QNXDEBUGSUPPORT_H
|
#ifndef QNX_INTERNAL_QNXDEBUGSUPPORT_H
|
||||||
#define QNX_INTERNAL_QNXDEBUGSUPPORT_H
|
#define QNX_INTERNAL_QNXDEBUGSUPPORT_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <projectexplorer/devicesupport/idevice.h>
|
||||||
|
|
||||||
namespace Debugger {
|
#include <QObject>
|
||||||
class DebuggerEngine;
|
#include <QString>
|
||||||
|
|
||||||
|
namespace Debugger { class DebuggerEngine; }
|
||||||
|
namespace ProjectExplorer {
|
||||||
|
class DeviceApplicationRunner;
|
||||||
|
class DeviceUsedPortsGatherer;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Qnx {
|
namespace Qnx {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class QnxApplicationRunner;
|
|
||||||
class QnxRunConfiguration;
|
class QnxRunConfiguration;
|
||||||
|
|
||||||
class QnxDebugSupport : public QObject
|
class QnxDebugSupport : public QObject
|
||||||
@@ -59,25 +63,30 @@ public slots:
|
|||||||
private slots:
|
private slots:
|
||||||
void handleAdapterSetupRequested();
|
void handleAdapterSetupRequested();
|
||||||
|
|
||||||
void startExecution();
|
|
||||||
void handleRemoteProcessStarted();
|
void handleRemoteProcessStarted();
|
||||||
void handleRemoteProcessFinished(qint64 exitCode);
|
void handleRemoteProcessFinished(bool success);
|
||||||
void handleProgressReport(const QString &progressOutput);
|
void handleProgressReport(const QString &progressOutput);
|
||||||
void handleRemoteOutput(const QByteArray &output);
|
void handleRemoteOutput(const QByteArray &output);
|
||||||
void handleSshError(const QString &error);
|
void handleError(const QString &error);
|
||||||
|
void handlePortListReady();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void startExecution();
|
||||||
void setFinished();
|
void setFinished();
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
Inactive,
|
Inactive,
|
||||||
StartingRunner,
|
GatheringPorts,
|
||||||
StartingRemoteProcess,
|
StartingRemoteProcess,
|
||||||
Debugging
|
Debugging
|
||||||
};
|
};
|
||||||
|
|
||||||
QnxApplicationRunner *m_runner;
|
const QString m_executable;
|
||||||
|
const QString m_commandPrefix;
|
||||||
|
const QString m_arguments;
|
||||||
|
ProjectExplorer::IDevice::ConstPtr m_device;
|
||||||
|
ProjectExplorer::DeviceApplicationRunner *m_runner;
|
||||||
|
ProjectExplorer::DeviceUsedPortsGatherer * m_portsGatherer;
|
||||||
Debugger::DebuggerEngine *m_engine;
|
Debugger::DebuggerEngine *m_engine;
|
||||||
int m_port;
|
int m_port;
|
||||||
|
|
||||||
|
@@ -32,21 +32,22 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "qnxruncontrol.h"
|
#include "qnxruncontrol.h"
|
||||||
#include "qnxapplicationrunner.h"
|
|
||||||
#include "qnxrunconfiguration.h"
|
#include "qnxrunconfiguration.h"
|
||||||
|
#include "qnxutils.h"
|
||||||
|
|
||||||
#include <projectexplorer/runconfiguration.h>
|
#include <projectexplorer/runconfiguration.h>
|
||||||
|
#include <remotelinux/remotelinuxrunconfiguration.h>
|
||||||
|
|
||||||
using namespace Qnx;
|
using namespace Qnx;
|
||||||
using namespace Qnx::Internal;
|
using namespace Qnx::Internal;
|
||||||
|
using namespace RemoteLinux;
|
||||||
|
|
||||||
QnxRunControl::QnxRunControl(ProjectExplorer::RunConfiguration *runConfig)
|
QnxRunControl::QnxRunControl(ProjectExplorer::RunConfiguration *runConfig)
|
||||||
: RemoteLinux::AbstractRemoteLinuxRunControl(runConfig)
|
: RemoteLinuxRunControl(runConfig)
|
||||||
, m_runner(new QnxApplicationRunner(qobject_cast<QnxRunConfiguration *>(runConfig), this))
|
|
||||||
{
|
{
|
||||||
}
|
const RemoteLinuxRunConfiguration * const rc
|
||||||
|
= qobject_cast<RemoteLinuxRunConfiguration *>(runConfig);
|
||||||
RemoteLinux::AbstractRemoteLinuxApplicationRunner *QnxRunControl::runner() const
|
QString executable = rc->remoteExecutableFilePath();
|
||||||
{
|
executable.replace(QLatin1String("/"), QLatin1String("\\/"));
|
||||||
return m_runner;
|
overrideStopCommandLine(QnxUtils::applicationKillCommand(executable).toUtf8());
|
||||||
}
|
}
|
||||||
|
@@ -39,18 +39,11 @@
|
|||||||
namespace Qnx {
|
namespace Qnx {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class QnxApplicationRunner;
|
class QnxRunControl : public RemoteLinux::RemoteLinuxRunControl
|
||||||
|
|
||||||
class QnxRunControl : public RemoteLinux::AbstractRemoteLinuxRunControl
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit QnxRunControl(ProjectExplorer::RunConfiguration *runConfig);
|
explicit QnxRunControl(ProjectExplorer::RunConfiguration *runConfig);
|
||||||
|
|
||||||
RemoteLinux::AbstractRemoteLinuxApplicationRunner *runner() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
QnxApplicationRunner * const m_runner;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -75,3 +75,11 @@ QStringList QnxUtils::searchPaths(QnxAbstractQtVersion *qtVersion)
|
|||||||
|
|
||||||
return searchPaths;
|
return searchPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString QnxUtils::applicationKillCommand(const QString &applicationFilePath)
|
||||||
|
{
|
||||||
|
return QString::fromLatin1("for PID in $(ps -f -o pid,comm | grep %1 | awk '/%1/ {print $1}'); "
|
||||||
|
"do "
|
||||||
|
"kill $PID; sleep 1; kill -9 $PID; "
|
||||||
|
"done").arg(applicationFilePath);
|
||||||
|
}
|
||||||
|
@@ -49,6 +49,7 @@ public:
|
|||||||
static QString addQuotes(const QString &string);
|
static QString addQuotes(const QString &string);
|
||||||
static Qnx::QnxArchitecture cpudirToArch(const QString &cpuDir);
|
static Qnx::QnxArchitecture cpudirToArch(const QString &cpuDir);
|
||||||
static QStringList searchPaths(QnxAbstractQtVersion *qtVersion);
|
static QStringList searchPaths(QnxAbstractQtVersion *qtVersion);
|
||||||
|
static QString applicationKillCommand(const QString &applicationFilePath);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -17,7 +17,6 @@ HEADERS += \
|
|||||||
genericlinuxdeviceconfigurationfactory.h \
|
genericlinuxdeviceconfigurationfactory.h \
|
||||||
remotelinuxrunconfigurationwidget.h \
|
remotelinuxrunconfigurationwidget.h \
|
||||||
remotelinuxrunconfigurationfactory.h \
|
remotelinuxrunconfigurationfactory.h \
|
||||||
remotelinuxapplicationrunner.h \
|
|
||||||
remotelinuxruncontrol.h \
|
remotelinuxruncontrol.h \
|
||||||
remotelinuxruncontrolfactory.h \
|
remotelinuxruncontrolfactory.h \
|
||||||
remotelinuxdebugsupport.h \
|
remotelinuxdebugsupport.h \
|
||||||
@@ -65,7 +64,6 @@ SOURCES += \
|
|||||||
genericlinuxdeviceconfigurationfactory.cpp \
|
genericlinuxdeviceconfigurationfactory.cpp \
|
||||||
remotelinuxrunconfigurationwidget.cpp \
|
remotelinuxrunconfigurationwidget.cpp \
|
||||||
remotelinuxrunconfigurationfactory.cpp \
|
remotelinuxrunconfigurationfactory.cpp \
|
||||||
remotelinuxapplicationrunner.cpp \
|
|
||||||
remotelinuxruncontrol.cpp \
|
remotelinuxruncontrol.cpp \
|
||||||
remotelinuxruncontrolfactory.cpp \
|
remotelinuxruncontrolfactory.cpp \
|
||||||
remotelinuxdebugsupport.cpp \
|
remotelinuxdebugsupport.cpp \
|
||||||
|
@@ -64,8 +64,6 @@ QtcPlugin {
|
|||||||
"remotelinux.qrc",
|
"remotelinux.qrc",
|
||||||
"remotelinux_constants.h",
|
"remotelinux_constants.h",
|
||||||
"remotelinux_export.h",
|
"remotelinux_export.h",
|
||||||
"remotelinuxapplicationrunner.cpp",
|
|
||||||
"remotelinuxapplicationrunner.h",
|
|
||||||
"remotelinuxcustomcommanddeploymentstep.h",
|
"remotelinuxcustomcommanddeploymentstep.h",
|
||||||
"remotelinuxcustomcommanddeployservice.cpp",
|
"remotelinuxcustomcommanddeployservice.cpp",
|
||||||
"remotelinuxcustomcommanddeployservice.h",
|
"remotelinuxcustomcommanddeployservice.h",
|
||||||
|
@@ -1,508 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator
|
|
||||||
**
|
|
||||||
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
|
||||||
**
|
|
||||||
** Contact: http://www.qt-project.org/
|
|
||||||
**
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
**
|
|
||||||
** 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, Nokia gives you certain additional
|
|
||||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
** Other Usage
|
|
||||||
**
|
|
||||||
** Alternatively, this file may be used in accordance with the terms and
|
|
||||||
** conditions contained in a signed written agreement between you and Nokia.
|
|
||||||
**
|
|
||||||
**
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "remotelinuxapplicationrunner.h"
|
|
||||||
|
|
||||||
#include "linuxdeviceconfiguration.h"
|
|
||||||
#include "remotelinuxrunconfiguration.h"
|
|
||||||
|
|
||||||
#include <projectexplorer/target.h>
|
|
||||||
#include <projectexplorer/profileinformation.h>
|
|
||||||
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
|
|
||||||
|
|
||||||
#include <utils/portlist.h>
|
|
||||||
#include <utils/qtcassert.h>
|
|
||||||
#include <ssh/sshconnection.h>
|
|
||||||
#include <ssh/sshconnectionmanager.h>
|
|
||||||
#include <ssh/sshremoteprocess.h>
|
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
|
||||||
using namespace QSsh;
|
|
||||||
using namespace Utils;
|
|
||||||
|
|
||||||
namespace RemoteLinux {
|
|
||||||
namespace Internal {
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
enum State {
|
|
||||||
Inactive, SettingUpDevice, Connecting, PreRunCleaning, AdditionalPreRunCleaning,
|
|
||||||
GatheringPorts, AdditionalInitializing, ReadyForExecution, ProcessStarting, ProcessStarted,
|
|
||||||
PostRunCleaning
|
|
||||||
};
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
class AbstractRemoteLinuxApplicationRunnerPrivate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AbstractRemoteLinuxApplicationRunnerPrivate(const RemoteLinuxRunConfiguration *runConfig)
|
|
||||||
: devConfig(DeviceProfileInformation::device(runConfig->target()->profile())),
|
|
||||||
remoteExecutable(runConfig->remoteExecutableFilePath()),
|
|
||||||
appArguments(runConfig->arguments()),
|
|
||||||
commandPrefix(runConfig->commandPrefix()),
|
|
||||||
initialFreePorts(devConfig->freePorts()),
|
|
||||||
connection(0),
|
|
||||||
stopRequested(false),
|
|
||||||
state(Inactive)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
DeviceUsedPortsGatherer portsGatherer;
|
|
||||||
IDevice::ConstPtr devConfig;
|
|
||||||
const QString remoteExecutable;
|
|
||||||
const QString appArguments;
|
|
||||||
const QString commandPrefix;
|
|
||||||
const PortList initialFreePorts;
|
|
||||||
|
|
||||||
QSsh::SshConnection *connection;
|
|
||||||
QSsh::SshRemoteProcess::Ptr runner;
|
|
||||||
QSsh::SshRemoteProcess::Ptr cleaner;
|
|
||||||
|
|
||||||
PortList freePorts;
|
|
||||||
int exitStatus;
|
|
||||||
bool stopRequested;
|
|
||||||
State state;
|
|
||||||
|
|
||||||
};
|
|
||||||
} // namespace Internal
|
|
||||||
|
|
||||||
|
|
||||||
using namespace Internal;
|
|
||||||
|
|
||||||
AbstractRemoteLinuxApplicationRunner::AbstractRemoteLinuxApplicationRunner(RemoteLinuxRunConfiguration *runConfig,
|
|
||||||
QObject *parent)
|
|
||||||
: QObject(parent), d(new AbstractRemoteLinuxApplicationRunnerPrivate(runConfig))
|
|
||||||
{
|
|
||||||
connect(&d->portsGatherer, SIGNAL(error(QString)), SLOT(handlePortsGathererError(QString)));
|
|
||||||
connect(&d->portsGatherer, SIGNAL(portListReady()), SLOT(handleUsedPortsAvailable()));
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRemoteLinuxApplicationRunner::~AbstractRemoteLinuxApplicationRunner()
|
|
||||||
{
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
|
|
||||||
SshConnection *AbstractRemoteLinuxApplicationRunner::connection() const
|
|
||||||
{
|
|
||||||
return d->connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
IDevice::ConstPtr AbstractRemoteLinuxApplicationRunner::devConfig() const
|
|
||||||
{
|
|
||||||
return d->devConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceUsedPortsGatherer *AbstractRemoteLinuxApplicationRunner::usedPortsGatherer() const
|
|
||||||
{
|
|
||||||
return &d->portsGatherer;
|
|
||||||
}
|
|
||||||
|
|
||||||
PortList *AbstractRemoteLinuxApplicationRunner::freePorts()
|
|
||||||
{
|
|
||||||
return &d->freePorts;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AbstractRemoteLinuxApplicationRunner::remoteExecutable() const
|
|
||||||
{
|
|
||||||
return d->remoteExecutable;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AbstractRemoteLinuxApplicationRunner::arguments() const
|
|
||||||
{
|
|
||||||
return d->appArguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AbstractRemoteLinuxApplicationRunner::commandPrefix() const
|
|
||||||
{
|
|
||||||
return d->commandPrefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::start()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(!d->stopRequested && d->state == Inactive, return);
|
|
||||||
|
|
||||||
QString errorMsg;
|
|
||||||
if (!canRun(errorMsg)) {
|
|
||||||
emitError(tr("Cannot run: %1").arg(errorMsg), true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->state = SettingUpDevice;
|
|
||||||
doDeviceSetup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::stop()
|
|
||||||
{
|
|
||||||
if (d->stopRequested)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (d->state) {
|
|
||||||
case Connecting:
|
|
||||||
setInactive();
|
|
||||||
emit remoteProcessFinished(InvalidExitCode);
|
|
||||||
break;
|
|
||||||
case GatheringPorts:
|
|
||||||
d->portsGatherer.stop();
|
|
||||||
setInactive();
|
|
||||||
emit remoteProcessFinished(InvalidExitCode);
|
|
||||||
break;
|
|
||||||
case SettingUpDevice:
|
|
||||||
case PreRunCleaning:
|
|
||||||
case AdditionalPreRunCleaning:
|
|
||||||
case AdditionalInitializing:
|
|
||||||
case ProcessStarting:
|
|
||||||
case PostRunCleaning:
|
|
||||||
d->stopRequested = true; // TODO: We might need stopPreRunCleaning() etc. for the subclasses
|
|
||||||
break;
|
|
||||||
case ReadyForExecution:
|
|
||||||
d->stopRequested = true;
|
|
||||||
d->state = PostRunCleaning;
|
|
||||||
doPostRunCleanup();
|
|
||||||
break;
|
|
||||||
case ProcessStarted:
|
|
||||||
d->stopRequested = true;
|
|
||||||
cleanup();
|
|
||||||
break;
|
|
||||||
case Inactive:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::handleConnected()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(d->state == Connecting, return);
|
|
||||||
|
|
||||||
if (d->stopRequested) {
|
|
||||||
emit remoteProcessFinished(InvalidExitCode);
|
|
||||||
setInactive();
|
|
||||||
} else {
|
|
||||||
d->state = PreRunCleaning;
|
|
||||||
cleanup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::handleConnectionFailure()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(d->state != Inactive, return);
|
|
||||||
|
|
||||||
if (d->state != Connecting || d->state != PreRunCleaning)
|
|
||||||
doAdditionalConnectionErrorHandling();
|
|
||||||
|
|
||||||
const QString errorMsg = d->state == Connecting
|
|
||||||
? tr("Could not connect to host: %1") : tr("Connection error: %1");
|
|
||||||
emitError(errorMsg.arg(d->connection->errorString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::cleanup()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(d->state == PreRunCleaning
|
|
||||||
|| (d->state == ProcessStarted && d->stopRequested), return);
|
|
||||||
|
|
||||||
emit reportProgress(tr("Killing remote process(es)..."));
|
|
||||||
d->cleaner = d->connection->createRemoteProcess(killApplicationCommandLine().toUtf8());
|
|
||||||
connect(d->cleaner.data(), SIGNAL(closed(int)), SLOT(handleCleanupFinished(int)));
|
|
||||||
d->cleaner->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::handleCleanupFinished(int exitStatus)
|
|
||||||
{
|
|
||||||
Q_ASSERT(exitStatus == SshRemoteProcess::FailedToStart
|
|
||||||
|| exitStatus == SshRemoteProcess::CrashExit
|
|
||||||
|| exitStatus == SshRemoteProcess::NormalExit);
|
|
||||||
|
|
||||||
QTC_ASSERT(d->state == PreRunCleaning
|
|
||||||
|| (d->state == ProcessStarted && d->stopRequested) || d->state == Inactive, return);
|
|
||||||
|
|
||||||
if (d->state == Inactive)
|
|
||||||
return;
|
|
||||||
if (d->stopRequested && d->state == PreRunCleaning) {
|
|
||||||
setInactive();
|
|
||||||
emit remoteProcessFinished(InvalidExitCode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (d->stopRequested) {
|
|
||||||
d->state = PostRunCleaning;
|
|
||||||
doPostRunCleanup();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exitStatus != SshRemoteProcess::NormalExit) {
|
|
||||||
emitError(tr("Initial cleanup failed: %1").arg(d->cleaner->errorString()));
|
|
||||||
emit remoteProcessFinished(InvalidExitCode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->state = AdditionalPreRunCleaning;
|
|
||||||
doAdditionalInitialCleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::startExecution(const QByteArray &remoteCall)
|
|
||||||
{
|
|
||||||
QTC_ASSERT(d->state == ReadyForExecution, return);
|
|
||||||
|
|
||||||
if (d->stopRequested)
|
|
||||||
return;
|
|
||||||
|
|
||||||
d->runner = d->connection->createRemoteProcess(remoteCall);
|
|
||||||
connect(d->runner.data(), SIGNAL(started()), SLOT(handleRemoteProcessStarted()));
|
|
||||||
connect(d->runner.data(), SIGNAL(closed(int)), SLOT(handleRemoteProcessFinished(int)));
|
|
||||||
connect(d->runner.data(), SIGNAL(readyReadStandardOutput()), SLOT(handleRemoteStdout()));
|
|
||||||
connect(d->runner.data(), SIGNAL(readyReadStandardError()), SLOT(handleRemoteStderr()));
|
|
||||||
d->state = ProcessStarting;
|
|
||||||
d->runner->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::handleRemoteProcessStarted()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(d->state == ProcessStarting, return);
|
|
||||||
|
|
||||||
d->state = ProcessStarted;
|
|
||||||
if (d->stopRequested) {
|
|
||||||
cleanup();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit reportProgress(tr("Remote process started."));
|
|
||||||
emit remoteProcessStarted();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::handleRemoteProcessFinished(int exitStatus)
|
|
||||||
{
|
|
||||||
Q_ASSERT(exitStatus == SshRemoteProcess::FailedToStart
|
|
||||||
|| exitStatus == SshRemoteProcess::CrashExit
|
|
||||||
|| exitStatus == SshRemoteProcess::NormalExit);
|
|
||||||
QTC_ASSERT(d->state == ProcessStarted || d->state == Inactive, return);
|
|
||||||
|
|
||||||
d->exitStatus = exitStatus;
|
|
||||||
if (!d->stopRequested && d->state != Inactive) {
|
|
||||||
d->state = PostRunCleaning;
|
|
||||||
doPostRunCleanup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::setInactive()
|
|
||||||
{
|
|
||||||
d->portsGatherer.stop();
|
|
||||||
if (d->connection) {
|
|
||||||
disconnect(d->connection, 0, this, 0);
|
|
||||||
SshConnectionManager::instance().releaseConnection(d->connection);
|
|
||||||
d->connection = 0;
|
|
||||||
}
|
|
||||||
if (d->cleaner)
|
|
||||||
disconnect(d->cleaner.data(), 0, this, 0);
|
|
||||||
d->stopRequested = false;
|
|
||||||
d->state = Inactive;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::emitError(const QString &errorMsg, bool force)
|
|
||||||
{
|
|
||||||
if (d->state != Inactive) {
|
|
||||||
setInactive();
|
|
||||||
emit error(errorMsg);
|
|
||||||
} else if (force) {
|
|
||||||
emit error(errorMsg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::handlePortsGathererError(const QString &errorMsg)
|
|
||||||
{
|
|
||||||
if (d->state != Inactive) {
|
|
||||||
if (connection()->errorState() != SshNoError) {
|
|
||||||
emitError(errorMsg);
|
|
||||||
} else {
|
|
||||||
emit reportProgress(tr("Gathering ports failed: %1\nContinuing anyway.").arg(errorMsg));
|
|
||||||
handleUsedPortsAvailable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::handleUsedPortsAvailable()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(d->state == GatheringPorts, return);
|
|
||||||
|
|
||||||
if (d->stopRequested) {
|
|
||||||
setInactive();
|
|
||||||
emit remoteProcessFinished(InvalidExitCode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->state = AdditionalInitializing;
|
|
||||||
doAdditionalInitializations();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::handleRemoteStdout()
|
|
||||||
{
|
|
||||||
emit remoteOutput(d->runner->readAllStandardOutput());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::handleRemoteStderr()
|
|
||||||
{
|
|
||||||
emit remoteErrorOutput(d->runner->readAllStandardError());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AbstractRemoteLinuxApplicationRunner::canRun(QString &whyNot) const
|
|
||||||
{
|
|
||||||
if (d->remoteExecutable.isEmpty()) {
|
|
||||||
whyNot = tr("No remote executable set.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!d->devConfig) {
|
|
||||||
whyNot = tr("No device configuration set.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::handleDeviceSetupDone(bool success)
|
|
||||||
{
|
|
||||||
QTC_ASSERT(d->state == SettingUpDevice, return);
|
|
||||||
|
|
||||||
if (!success || d->stopRequested) {
|
|
||||||
setInactive();
|
|
||||||
emit remoteProcessFinished(InvalidExitCode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->connection = SshConnectionManager::instance().acquireConnection(d->devConfig->sshParameters());
|
|
||||||
d->state = Connecting;
|
|
||||||
d->exitStatus = -1;
|
|
||||||
d->freePorts = d->initialFreePorts;
|
|
||||||
connect(d->connection, SIGNAL(connected()), SLOT(handleConnected()));
|
|
||||||
connect(d->connection, SIGNAL(error(QSsh::SshError)),
|
|
||||||
SLOT(handleConnectionFailure()));
|
|
||||||
if (d->connection->state() == SshConnection::Connected) {
|
|
||||||
handleConnected();
|
|
||||||
} else {
|
|
||||||
emit reportProgress(tr("Connecting to device..."));
|
|
||||||
if (d->connection->state() == QSsh::SshConnection::Unconnected)
|
|
||||||
d->connection->connectToHost();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::handleInitialCleanupDone(bool success)
|
|
||||||
{
|
|
||||||
QTC_ASSERT(d->state == AdditionalPreRunCleaning, return);
|
|
||||||
|
|
||||||
if (!success || d->stopRequested) {
|
|
||||||
setInactive();
|
|
||||||
emit remoteProcessFinished(InvalidExitCode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->state = GatheringPorts;
|
|
||||||
d->portsGatherer.start(d->devConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::handleInitializationsDone(bool success)
|
|
||||||
{
|
|
||||||
QTC_ASSERT(d->state == AdditionalInitializing, return);
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
setInactive();
|
|
||||||
emit remoteProcessFinished(InvalidExitCode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (d->stopRequested) {
|
|
||||||
d->state = PostRunCleaning;
|
|
||||||
doPostRunCleanup();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->state = ReadyForExecution;
|
|
||||||
emit readyForExecution();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxApplicationRunner::handlePostRunCleanupDone()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(d->state == PostRunCleaning, return);
|
|
||||||
|
|
||||||
const bool wasStopRequested = d->stopRequested;
|
|
||||||
setInactive();
|
|
||||||
if (wasStopRequested)
|
|
||||||
emit remoteProcessFinished(InvalidExitCode);
|
|
||||||
else if (d->exitStatus == SshRemoteProcess::NormalExit)
|
|
||||||
emit remoteProcessFinished(d->runner->exitCode());
|
|
||||||
else
|
|
||||||
emit error(tr("Error running remote process: %1").arg(d->runner->errorString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AbstractRemoteLinuxApplicationRunner::killApplicationCommandLine() const
|
|
||||||
{
|
|
||||||
return QString::fromLatin1("cd /proc; for pid in `ls -d [0123456789]*`; "
|
|
||||||
"do "
|
|
||||||
"if [ \"`readlink /proc/$pid/exe`\" = \"%1\" ]; then "
|
|
||||||
" kill $pid; sleep 1; kill -9 $pid; "
|
|
||||||
"fi; "
|
|
||||||
"done").arg(remoteExecutable());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const qint64 AbstractRemoteLinuxApplicationRunner::InvalidExitCode = std::numeric_limits<qint64>::min();
|
|
||||||
|
|
||||||
|
|
||||||
GenericRemoteLinuxApplicationRunner::GenericRemoteLinuxApplicationRunner(RemoteLinuxRunConfiguration *runConfig,
|
|
||||||
QObject *parent)
|
|
||||||
: AbstractRemoteLinuxApplicationRunner(runConfig, parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GenericRemoteLinuxApplicationRunner::~GenericRemoteLinuxApplicationRunner()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GenericRemoteLinuxApplicationRunner::doDeviceSetup()
|
|
||||||
{
|
|
||||||
handleDeviceSetupDone(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenericRemoteLinuxApplicationRunner::doAdditionalInitialCleanup()
|
|
||||||
{
|
|
||||||
handleInitialCleanupDone(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenericRemoteLinuxApplicationRunner::doAdditionalInitializations()
|
|
||||||
{
|
|
||||||
handleInitializationsDone(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenericRemoteLinuxApplicationRunner::doPostRunCleanup()
|
|
||||||
{
|
|
||||||
handlePostRunCleanupDone();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenericRemoteLinuxApplicationRunner::doAdditionalConnectionErrorHandling()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace RemoteLinux
|
|
||||||
|
|
@@ -1,145 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator
|
|
||||||
**
|
|
||||||
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
|
||||||
**
|
|
||||||
** Contact: http://www.qt-project.org/
|
|
||||||
**
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
**
|
|
||||||
** 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, Nokia gives you certain additional
|
|
||||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
** Other Usage
|
|
||||||
**
|
|
||||||
** Alternatively, this file may be used in accordance with the terms and
|
|
||||||
** conditions contained in a signed written agreement between you and Nokia.
|
|
||||||
**
|
|
||||||
**
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef REMOTELINUXAPPLICATIONRUNNER_H
|
|
||||||
#define REMOTELINUXAPPLICATIONRUNNER_H
|
|
||||||
|
|
||||||
#include "remotelinux_export.h"
|
|
||||||
|
|
||||||
#include <projectexplorer/devicesupport/idevice.h>
|
|
||||||
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
|
|
||||||
|
|
||||||
namespace QSsh { class SshConnection; }
|
|
||||||
namespace Utils { class PortList; }
|
|
||||||
|
|
||||||
namespace RemoteLinux {
|
|
||||||
class RemoteLinuxRunConfiguration;
|
|
||||||
|
|
||||||
namespace Internal { class AbstractRemoteLinuxApplicationRunnerPrivate; }
|
|
||||||
|
|
||||||
class REMOTELINUX_EXPORT AbstractRemoteLinuxApplicationRunner : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_DISABLE_COPY(AbstractRemoteLinuxApplicationRunner)
|
|
||||||
public:
|
|
||||||
AbstractRemoteLinuxApplicationRunner(RemoteLinuxRunConfiguration *runConfig,
|
|
||||||
QObject *parent = 0);
|
|
||||||
~AbstractRemoteLinuxApplicationRunner();
|
|
||||||
|
|
||||||
void start();
|
|
||||||
void stop();
|
|
||||||
|
|
||||||
void startExecution(const QByteArray &remoteCall);
|
|
||||||
|
|
||||||
ProjectExplorer::IDevice::ConstPtr devConfig() const;
|
|
||||||
QSsh::SshConnection *connection() const;
|
|
||||||
ProjectExplorer::DeviceUsedPortsGatherer *usedPortsGatherer() const;
|
|
||||||
Utils::PortList *freePorts();
|
|
||||||
QString remoteExecutable() const;
|
|
||||||
QString arguments() const;
|
|
||||||
QString commandPrefix() const;
|
|
||||||
|
|
||||||
static const qint64 InvalidExitCode;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void error(const QString &error);
|
|
||||||
void readyForExecution();
|
|
||||||
void remoteOutput(const QByteArray &output);
|
|
||||||
void remoteErrorOutput(const QByteArray &output);
|
|
||||||
void reportProgress(const QString &progressOutput);
|
|
||||||
void remoteProcessStarted();
|
|
||||||
void remoteProcessFinished(qint64 exitCode);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Override to to additional checks.
|
|
||||||
virtual bool canRun(QString &whyNot) const;
|
|
||||||
|
|
||||||
void handleDeviceSetupDone(bool success);
|
|
||||||
void handleInitialCleanupDone(bool success);
|
|
||||||
void handleInitializationsDone(bool success);
|
|
||||||
void handlePostRunCleanupDone();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void handleConnected();
|
|
||||||
void handleConnectionFailure();
|
|
||||||
void handleCleanupFinished(int exitStatus);
|
|
||||||
void handleRemoteProcessStarted();
|
|
||||||
void handleRemoteProcessFinished(int exitStatus);
|
|
||||||
void handlePortsGathererError(const QString &errorMsg);
|
|
||||||
void handleUsedPortsAvailable();
|
|
||||||
void handleRemoteStdout();
|
|
||||||
void handleRemoteStderr();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
virtual QString killApplicationCommandLine() const;
|
|
||||||
|
|
||||||
// Implement to do custom setup of the device *before* connecting.
|
|
||||||
// Call handleDeviceSetupDone() afterwards.
|
|
||||||
virtual void doDeviceSetup() = 0;
|
|
||||||
|
|
||||||
// Implement to do additional pre-run cleanup and call handleInitialCleanupDone().
|
|
||||||
virtual void doAdditionalInitialCleanup() = 0;
|
|
||||||
|
|
||||||
// Implement to do additional initializations right before the application is ready.
|
|
||||||
// Call handleInitializationsDone() afterwards.
|
|
||||||
virtual void doAdditionalInitializations() = 0;
|
|
||||||
|
|
||||||
// Implement to do cleanups after application exit and call handlePostRunCleanupDone();
|
|
||||||
virtual void doPostRunCleanup() = 0;
|
|
||||||
|
|
||||||
virtual void doAdditionalConnectionErrorHandling() = 0;
|
|
||||||
|
|
||||||
void setInactive();
|
|
||||||
void emitError(const QString &errorMsg, bool force = false);
|
|
||||||
void cleanup();
|
|
||||||
|
|
||||||
Internal::AbstractRemoteLinuxApplicationRunnerPrivate * const d;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class REMOTELINUX_EXPORT GenericRemoteLinuxApplicationRunner : public AbstractRemoteLinuxApplicationRunner
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
GenericRemoteLinuxApplicationRunner(RemoteLinuxRunConfiguration *runConfig,
|
|
||||||
QObject *parent = 0);
|
|
||||||
~GenericRemoteLinuxApplicationRunner();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void doDeviceSetup();
|
|
||||||
void doAdditionalInitialCleanup();
|
|
||||||
void doAdditionalInitializations();
|
|
||||||
void doPostRunCleanup();
|
|
||||||
void doAdditionalConnectionErrorHandling();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace RemoteLinux
|
|
||||||
|
|
||||||
#endif // REMOTELINUXAPPLICATIONRUNNER_H
|
|
@@ -29,8 +29,8 @@
|
|||||||
|
|
||||||
#include "remotelinuxdebugsupport.h"
|
#include "remotelinuxdebugsupport.h"
|
||||||
|
|
||||||
#include "remotelinuxapplicationrunner.h"
|
|
||||||
#include "remotelinuxrunconfiguration.h"
|
#include "remotelinuxrunconfiguration.h"
|
||||||
|
#include "remotelinuxutils.h"
|
||||||
|
|
||||||
#include <debugger/debuggerengine.h>
|
#include <debugger/debuggerengine.h>
|
||||||
#include <debugger/debuggerstartparameters.h>
|
#include <debugger/debuggerstartparameters.h>
|
||||||
@@ -42,6 +42,8 @@
|
|||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
#include <projectexplorer/toolchain.h>
|
#include <projectexplorer/toolchain.h>
|
||||||
|
#include <projectexplorer/devicesupport/deviceapplicationrunner.h>
|
||||||
|
#include <utils/portlist.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
@@ -54,19 +56,23 @@ using namespace ProjectExplorer;
|
|||||||
namespace RemoteLinux {
|
namespace RemoteLinux {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
namespace {
|
namespace {
|
||||||
enum State { Inactive, StartingRunner, StartingRemoteProcess, Debugging };
|
enum State { Inactive, GatheringPorts, StartingRunner, Debugging };
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
class AbstractRemoteLinuxDebugSupportPrivate
|
class LinuxDeviceDebugSupportPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AbstractRemoteLinuxDebugSupportPrivate(RunConfiguration *runConfig,
|
LinuxDeviceDebugSupportPrivate(const RemoteLinuxRunConfiguration *runConfig,
|
||||||
DebuggerEngine *engine)
|
DebuggerEngine *engine)
|
||||||
: engine(engine),
|
: engine(engine),
|
||||||
qmlDebugging(runConfig->debuggerAspect()->useQmlDebugger()),
|
qmlDebugging(runConfig->debuggerAspect()->useQmlDebugger()),
|
||||||
cppDebugging(runConfig->debuggerAspect()->useCppDebugger()),
|
cppDebugging(runConfig->debuggerAspect()->useCppDebugger()),
|
||||||
state(Inactive),
|
state(Inactive),
|
||||||
gdbServerPort(-1), qmlPort(-1)
|
gdbServerPort(-1), qmlPort(-1),
|
||||||
|
device(DeviceProfileInformation::device(runConfig->target()->profile())),
|
||||||
|
remoteFilePath(runConfig->remoteExecutableFilePath()),
|
||||||
|
arguments(runConfig->arguments()),
|
||||||
|
commandPrefix(runConfig->commandPrefix())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,21 +83,20 @@ public:
|
|||||||
State state;
|
State state;
|
||||||
int gdbServerPort;
|
int gdbServerPort;
|
||||||
int qmlPort;
|
int qmlPort;
|
||||||
};
|
DeviceApplicationRunner appRunner;
|
||||||
|
DeviceUsedPortsGatherer portsGatherer;
|
||||||
class RemoteLinuxDebugSupportPrivate
|
const ProjectExplorer::IDevice::ConstPtr device;
|
||||||
{
|
Utils::PortList portList;
|
||||||
public:
|
const QString remoteFilePath;
|
||||||
RemoteLinuxDebugSupportPrivate(RemoteLinuxRunConfiguration *runConfig) : runner(runConfig) {}
|
const QString arguments;
|
||||||
|
const QString commandPrefix;
|
||||||
GenericRemoteLinuxApplicationRunner runner;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|
||||||
using namespace Internal;
|
using namespace Internal;
|
||||||
|
|
||||||
DebuggerStartParameters AbstractRemoteLinuxDebugSupport::startParameters(const RemoteLinuxRunConfiguration *runConfig)
|
DebuggerStartParameters LinuxDeviceDebugSupport::startParameters(const RemoteLinuxRunConfiguration *runConfig)
|
||||||
{
|
{
|
||||||
DebuggerStartParameters params;
|
DebuggerStartParameters params;
|
||||||
Target *target = runConfig->target();
|
Target *target = runConfig->target();
|
||||||
@@ -130,39 +135,90 @@ DebuggerStartParameters AbstractRemoteLinuxDebugSupport::startParameters(const R
|
|||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractRemoteLinuxDebugSupport::AbstractRemoteLinuxDebugSupport(RunConfiguration *runConfig,
|
LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunConfiguration *runConfig,
|
||||||
DebuggerEngine *engine)
|
DebuggerEngine *engine)
|
||||||
: QObject(engine), d(new AbstractRemoteLinuxDebugSupportPrivate(runConfig, engine))
|
: QObject(engine),
|
||||||
|
d(new LinuxDeviceDebugSupportPrivate(static_cast<RemoteLinuxRunConfiguration *>(runConfig), engine))
|
||||||
{
|
{
|
||||||
connect(d->engine, SIGNAL(requestRemoteSetup()), this, SLOT(handleRemoteSetupRequested()));
|
connect(d->engine, SIGNAL(requestRemoteSetup()), this, SLOT(handleRemoteSetupRequested()));
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractRemoteLinuxDebugSupport::~AbstractRemoteLinuxDebugSupport()
|
LinuxDeviceDebugSupport::~LinuxDeviceDebugSupport()
|
||||||
{
|
{
|
||||||
setFinished();
|
setFinished();
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDebugSupport::showMessage(const QString &msg, int channel)
|
void LinuxDeviceDebugSupport::setApplicationRunnerPreRunAction(DeviceApplicationHelperAction *action)
|
||||||
{
|
{
|
||||||
if (d->engine)
|
d->appRunner.setPreRunAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxDeviceDebugSupport::setApplicationRunnerPostRunAction(DeviceApplicationHelperAction *action)
|
||||||
|
{
|
||||||
|
d->appRunner.setPostRunAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxDeviceDebugSupport::showMessage(const QString &msg, int channel)
|
||||||
|
{
|
||||||
|
if (d->state != Inactive && d->engine)
|
||||||
d->engine->showMessage(msg, channel);
|
d->engine->showMessage(msg, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDebugSupport::handleRemoteSetupRequested()
|
void LinuxDeviceDebugSupport::handleRemoteSetupRequested()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(d->state == Inactive, return);
|
QTC_ASSERT(d->state == Inactive, return);
|
||||||
|
|
||||||
d->state = StartingRunner;
|
d->state = GatheringPorts;
|
||||||
showMessage(tr("Preparing remote side...\n"), AppStuff);
|
showMessage(tr("Checking available ports...\n"), LogStatus);
|
||||||
disconnect(runner(), 0, this, 0);
|
connect(&d->portsGatherer, SIGNAL(error(QString)), SLOT(handlePortsGathererError(QString)));
|
||||||
connect(runner(), SIGNAL(error(QString)), this, SLOT(handleSshError(QString)));
|
connect(&d->portsGatherer, SIGNAL(portListReady()), SLOT(handlePortListReady()));
|
||||||
connect(runner(), SIGNAL(readyForExecution()), this, SLOT(startExecution()));
|
d->portsGatherer.start(d->device);
|
||||||
connect(runner(), SIGNAL(reportProgress(QString)), this, SLOT(handleProgressReport(QString)));
|
|
||||||
runner()->start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDebugSupport::handleSshError(const QString &error)
|
void LinuxDeviceDebugSupport::handlePortsGathererError(const QString &message)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->state == GatheringPorts, return);
|
||||||
|
handleAdapterSetupFailed(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxDeviceDebugSupport::handlePortListReady()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->state == GatheringPorts, return);
|
||||||
|
|
||||||
|
d->portList = d->device->freePorts();
|
||||||
|
startExecution();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxDeviceDebugSupport::startExecution()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->state == GatheringPorts, return);
|
||||||
|
|
||||||
|
if (d->cppDebugging && !setPort(d->gdbServerPort))
|
||||||
|
return;
|
||||||
|
if (d->qmlDebugging && !setPort(d->qmlPort))
|
||||||
|
return;
|
||||||
|
|
||||||
|
d->state = StartingRunner;
|
||||||
|
d->gdbserverOutput.clear();
|
||||||
|
|
||||||
|
connect(&d->appRunner, SIGNAL(remoteStderr(QByteArray)),
|
||||||
|
SLOT(handleRemoteErrorOutput(QByteArray)));
|
||||||
|
connect(&d->appRunner, SIGNAL(remoteStdout(QByteArray)), SLOT(handleRemoteOutput(QByteArray)));
|
||||||
|
if (d->qmlDebugging && !d->cppDebugging)
|
||||||
|
connect(&d->appRunner, SIGNAL(remoteProcessStarted()), SLOT(handleRemoteProcessStarted()));
|
||||||
|
QString args = d->arguments;
|
||||||
|
if (d->qmlDebugging)
|
||||||
|
args += QString::fromLocal8Bit(" -qmljsdebugger=port:%1,block").arg(d->qmlPort);
|
||||||
|
const QString remoteCommandLine = (d->qmlDebugging && !d->cppDebugging)
|
||||||
|
? QString::fromLatin1("%1 %2 %3").arg(d->commandPrefix).arg(d->remoteFilePath).arg(args)
|
||||||
|
: QString::fromLatin1("%1 gdbserver :%2 %3 %4").arg(d->commandPrefix)
|
||||||
|
.arg(d->gdbServerPort).arg(d->remoteFilePath).arg(args);
|
||||||
|
connect(&d->appRunner, SIGNAL(finished(bool)), SLOT(handleAppRunnerFinished(bool)));
|
||||||
|
d->appRunner.start(d->device, remoteCommandLine.toUtf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxDeviceDebugSupport::handleAppRunnerError(const QString &error)
|
||||||
{
|
{
|
||||||
if (d->state == Debugging) {
|
if (d->state == Debugging) {
|
||||||
showMessage(error, AppError);
|
showMessage(error, AppError);
|
||||||
@@ -173,49 +229,7 @@ void AbstractRemoteLinuxDebugSupport::handleSshError(const QString &error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDebugSupport::startExecution()
|
void LinuxDeviceDebugSupport::handleAppRunnerFinished(bool success)
|
||||||
{
|
|
||||||
if (d->state == Inactive)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QTC_ASSERT(d->state == StartingRunner, return);
|
|
||||||
|
|
||||||
if (d->cppDebugging && !setPort(d->gdbServerPort))
|
|
||||||
return;
|
|
||||||
if (d->qmlDebugging && !setPort(d->qmlPort))
|
|
||||||
return;
|
|
||||||
|
|
||||||
d->state = StartingRemoteProcess;
|
|
||||||
d->gdbserverOutput.clear();
|
|
||||||
connect(runner(), SIGNAL(remoteErrorOutput(QByteArray)), this,
|
|
||||||
SLOT(handleRemoteErrorOutput(QByteArray)));
|
|
||||||
connect(runner(), SIGNAL(remoteOutput(QByteArray)), this,
|
|
||||||
SLOT(handleRemoteOutput(QByteArray)));
|
|
||||||
if (d->qmlDebugging && !d->cppDebugging) {
|
|
||||||
connect(runner(), SIGNAL(remoteProcessStarted()),
|
|
||||||
SLOT(handleRemoteProcessStarted()));
|
|
||||||
}
|
|
||||||
const QString &remoteExe = runner()->remoteExecutable();
|
|
||||||
QString args = runner()->arguments();
|
|
||||||
if (d->qmlDebugging) {
|
|
||||||
args += QString::fromLatin1(" -qmljsdebugger=port:%1,block")
|
|
||||||
.arg(d->qmlPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
const QHostAddress peerAddress = runner()->connection()->connectionInfo().peerAddress;
|
|
||||||
QString peerAddressString = peerAddress.toString();
|
|
||||||
if (peerAddress.protocol() == QAbstractSocket::IPv6Protocol)
|
|
||||||
peerAddressString.prepend(QLatin1Char('[')).append(QLatin1Char(']'));
|
|
||||||
const QString remoteCommandLine = (d->qmlDebugging && !d->cppDebugging)
|
|
||||||
? QString::fromLatin1("%1 %2 %3").arg(runner()->commandPrefix()).arg(remoteExe).arg(args)
|
|
||||||
: QString::fromLatin1("%1 gdbserver %5:%2 %3 %4").arg(runner()->commandPrefix())
|
|
||||||
.arg(d->gdbServerPort).arg(remoteExe).arg(args).arg(peerAddressString);
|
|
||||||
connect(runner(), SIGNAL(remoteProcessFinished(qint64)),
|
|
||||||
SLOT(handleRemoteProcessFinished(qint64)));
|
|
||||||
runner()->startExecution(remoteCommandLine.toUtf8());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxDebugSupport::handleRemoteProcessFinished(qint64 exitCode)
|
|
||||||
{
|
{
|
||||||
if (!d->engine || d->state == Inactive)
|
if (!d->engine || d->state == Inactive)
|
||||||
return;
|
return;
|
||||||
@@ -224,39 +238,35 @@ void AbstractRemoteLinuxDebugSupport::handleRemoteProcessFinished(qint64 exitCod
|
|||||||
// The QML engine does not realize on its own that the application has finished.
|
// The QML engine does not realize on its own that the application has finished.
|
||||||
if (d->qmlDebugging && !d->cppDebugging)
|
if (d->qmlDebugging && !d->cppDebugging)
|
||||||
d->engine->quitDebugger();
|
d->engine->quitDebugger();
|
||||||
else if (exitCode != 0)
|
else if (!success)
|
||||||
d->engine->notifyInferiorIll();
|
d->engine->notifyInferiorIll();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
const QString errorMsg = (d->qmlDebugging && !d->cppDebugging)
|
d->engine->notifyEngineRemoteSetupFailed(tr("Debugging failed."));
|
||||||
? tr("Remote application failed with exit code %1.").arg(exitCode)
|
|
||||||
: tr("The gdbserver process closed unexpectedly.");
|
|
||||||
d->engine->notifyEngineRemoteSetupFailed(errorMsg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDebugSupport::handleDebuggingFinished()
|
void LinuxDeviceDebugSupport::handleDebuggingFinished()
|
||||||
{
|
{
|
||||||
setFinished();
|
setFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDebugSupport::handleRemoteOutput(const QByteArray &output)
|
void LinuxDeviceDebugSupport::handleRemoteOutput(const QByteArray &output)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(d->state == Inactive || d->state == Debugging, return);
|
QTC_ASSERT(d->state == Inactive || d->state == Debugging, return);
|
||||||
|
|
||||||
showMessage(QString::fromUtf8(output), AppOutput);
|
showMessage(QString::fromUtf8(output), AppOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDebugSupport::handleRemoteErrorOutput(const QByteArray &output)
|
void LinuxDeviceDebugSupport::handleRemoteErrorOutput(const QByteArray &output)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(d->state == Inactive || d->state == StartingRemoteProcess || d->state == Debugging,
|
QTC_ASSERT(d->state != GatheringPorts, return);
|
||||||
return);
|
|
||||||
|
|
||||||
if (!d->engine)
|
if (!d->engine)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
showMessage(QString::fromUtf8(output), AppOutput);
|
showMessage(QString::fromUtf8(output), AppError);
|
||||||
if (d->state == StartingRemoteProcess && d->cppDebugging) {
|
if (d->state == StartingRunner && d->cppDebugging) {
|
||||||
d->gdbserverOutput += output;
|
d->gdbserverOutput += output;
|
||||||
if (d->gdbserverOutput.contains("Listening on port")) {
|
if (d->gdbserverOutput.contains("Listening on port")) {
|
||||||
handleAdapterSetupDone();
|
handleAdapterSetupDone();
|
||||||
@@ -265,42 +275,45 @@ void AbstractRemoteLinuxDebugSupport::handleRemoteErrorOutput(const QByteArray &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDebugSupport::handleProgressReport(const QString &progressOutput)
|
void LinuxDeviceDebugSupport::handleProgressReport(const QString &progressOutput)
|
||||||
{
|
{
|
||||||
showMessage(progressOutput + QLatin1Char('\n'), AppStuff);
|
showMessage(progressOutput + QLatin1Char('\n'), LogStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDebugSupport::handleAdapterSetupFailed(const QString &error)
|
void LinuxDeviceDebugSupport::handleAdapterSetupFailed(const QString &error)
|
||||||
{
|
{
|
||||||
setFinished();
|
setFinished();
|
||||||
d->engine->notifyEngineRemoteSetupFailed(tr("Initial setup failed: %1").arg(error));
|
d->engine->notifyEngineRemoteSetupFailed(tr("Initial setup failed: %1").arg(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDebugSupport::handleAdapterSetupDone()
|
void LinuxDeviceDebugSupport::handleAdapterSetupDone()
|
||||||
{
|
{
|
||||||
d->state = Debugging;
|
d->state = Debugging;
|
||||||
d->engine->notifyEngineRemoteSetupDone(d->gdbServerPort, d->qmlPort);
|
d->engine->notifyEngineRemoteSetupDone(d->gdbServerPort, d->qmlPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDebugSupport::handleRemoteProcessStarted()
|
void LinuxDeviceDebugSupport::handleRemoteProcessStarted()
|
||||||
{
|
{
|
||||||
Q_ASSERT(d->qmlDebugging && !d->cppDebugging);
|
QTC_ASSERT(d->qmlDebugging && !d->cppDebugging, return);
|
||||||
QTC_ASSERT(d->state == StartingRemoteProcess, return);
|
QTC_ASSERT(d->state == StartingRunner, return);
|
||||||
|
|
||||||
handleAdapterSetupDone();
|
handleAdapterSetupDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxDebugSupport::setFinished()
|
void LinuxDeviceDebugSupport::setFinished()
|
||||||
{
|
{
|
||||||
if (d->state == Inactive)
|
if (d->state == Inactive)
|
||||||
return;
|
return;
|
||||||
|
d->portsGatherer.disconnect(this);
|
||||||
|
d->appRunner.disconnect(this);
|
||||||
|
if (d->state == StartingRunner)
|
||||||
|
d->appRunner.stop(RemoteLinuxUtils::killApplicationCommandLine(d->remoteFilePath).toUtf8());
|
||||||
d->state = Inactive;
|
d->state = Inactive;
|
||||||
runner()->stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AbstractRemoteLinuxDebugSupport::setPort(int &port)
|
bool LinuxDeviceDebugSupport::setPort(int &port)
|
||||||
{
|
{
|
||||||
port = runner()->usedPortsGatherer()->getNextFreePort(runner()->freePorts());
|
port = d->portsGatherer.getNextFreePort(&d->portList);
|
||||||
if (port == -1) {
|
if (port == -1) {
|
||||||
handleAdapterSetupFailed(tr("Not enough free ports on device for debugging."));
|
handleAdapterSetupFailed(tr("Not enough free ports on device for debugging."));
|
||||||
return false;
|
return false;
|
||||||
@@ -308,22 +321,4 @@ bool AbstractRemoteLinuxDebugSupport::setPort(int &port)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RemoteLinuxDebugSupport::RemoteLinuxDebugSupport(RemoteLinuxRunConfiguration *runConfig,
|
|
||||||
DebuggerEngine *engine)
|
|
||||||
: AbstractRemoteLinuxDebugSupport(runConfig, engine),
|
|
||||||
d(new RemoteLinuxDebugSupportPrivate(runConfig))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoteLinuxDebugSupport::~RemoteLinuxDebugSupport()
|
|
||||||
{
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRemoteLinuxApplicationRunner *RemoteLinuxDebugSupport::runner() const
|
|
||||||
{
|
|
||||||
return &d->runner;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace RemoteLinux
|
} // namespace RemoteLinux
|
||||||
|
@@ -40,65 +40,49 @@ class DebuggerStartParameters;
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
class RunControl;
|
class DeviceApplicationHelperAction;
|
||||||
class RunConfiguration;
|
class RunConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace RemoteLinux {
|
namespace RemoteLinux {
|
||||||
class RemoteLinuxRunConfiguration;
|
class RemoteLinuxRunConfiguration;
|
||||||
class AbstractRemoteLinuxApplicationRunner;
|
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal { class LinuxDeviceDebugSupportPrivate; }
|
||||||
class AbstractRemoteLinuxDebugSupportPrivate;
|
|
||||||
class RemoteLinuxDebugSupportPrivate;
|
|
||||||
} // namespace Internal
|
|
||||||
|
|
||||||
class REMOTELINUX_EXPORT AbstractRemoteLinuxDebugSupport : public QObject
|
class REMOTELINUX_EXPORT LinuxDeviceDebugSupport : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_DISABLE_COPY(AbstractRemoteLinuxDebugSupport)
|
|
||||||
public:
|
public:
|
||||||
static Debugger::DebuggerStartParameters startParameters(const RemoteLinuxRunConfiguration *runConfig);
|
static Debugger::DebuggerStartParameters startParameters(const RemoteLinuxRunConfiguration *runConfig);
|
||||||
|
|
||||||
AbstractRemoteLinuxDebugSupport(ProjectExplorer::RunConfiguration *runConfig,
|
LinuxDeviceDebugSupport(ProjectExplorer::RunConfiguration *runConfig,
|
||||||
Debugger::DebuggerEngine *engine);
|
Debugger::DebuggerEngine *engine);
|
||||||
~AbstractRemoteLinuxDebugSupport();
|
~LinuxDeviceDebugSupport();
|
||||||
|
|
||||||
|
void setApplicationRunnerPreRunAction(ProjectExplorer::DeviceApplicationHelperAction *action);
|
||||||
|
void setApplicationRunnerPostRunAction(ProjectExplorer::DeviceApplicationHelperAction *action);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleRemoteSetupRequested();
|
void handleRemoteSetupRequested();
|
||||||
void handleSshError(const QString &error);
|
void handleAppRunnerError(const QString &error);
|
||||||
void startExecution();
|
void startExecution();
|
||||||
void handleDebuggingFinished();
|
void handleDebuggingFinished();
|
||||||
void handleRemoteOutput(const QByteArray &output);
|
void handleRemoteOutput(const QByteArray &output);
|
||||||
void handleRemoteErrorOutput(const QByteArray &output);
|
void handleRemoteErrorOutput(const QByteArray &output);
|
||||||
void handleProgressReport(const QString &progressOutput);
|
void handleProgressReport(const QString &progressOutput);
|
||||||
void handleRemoteProcessStarted();
|
void handleRemoteProcessStarted();
|
||||||
void handleRemoteProcessFinished(qint64 exitCode);
|
void handleAppRunnerFinished(bool success);
|
||||||
|
void handlePortsGathererError(const QString &message);
|
||||||
|
void handlePortListReady();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual AbstractRemoteLinuxApplicationRunner *runner() const = 0;
|
|
||||||
|
|
||||||
void handleAdapterSetupFailed(const QString &error);
|
void handleAdapterSetupFailed(const QString &error);
|
||||||
void handleAdapterSetupDone();
|
void handleAdapterSetupDone();
|
||||||
void setFinished();
|
void setFinished();
|
||||||
bool setPort(int &port);
|
bool setPort(int &port);
|
||||||
void showMessage(const QString &msg, int channel);
|
void showMessage(const QString &msg, int channel);
|
||||||
|
|
||||||
Internal::AbstractRemoteLinuxDebugSupportPrivate * const d;
|
Internal::LinuxDeviceDebugSupportPrivate * const d;
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class REMOTELINUX_EXPORT RemoteLinuxDebugSupport : public AbstractRemoteLinuxDebugSupport
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
RemoteLinuxDebugSupport(RemoteLinuxRunConfiguration *runConfig, Debugger::DebuggerEngine *engine);
|
|
||||||
~RemoteLinuxDebugSupport();
|
|
||||||
|
|
||||||
private:
|
|
||||||
AbstractRemoteLinuxApplicationRunner *runner() const;
|
|
||||||
|
|
||||||
Internal::RemoteLinuxDebugSupportPrivate * const d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace RemoteLinux
|
} // namespace RemoteLinux
|
||||||
|
@@ -29,10 +29,13 @@
|
|||||||
|
|
||||||
#include "remotelinuxruncontrol.h"
|
#include "remotelinuxruncontrol.h"
|
||||||
|
|
||||||
#include "remotelinuxapplicationrunner.h"
|
|
||||||
#include "remotelinuxrunconfiguration.h"
|
#include "remotelinuxrunconfiguration.h"
|
||||||
|
#include "remotelinuxutils.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/devicesupport/deviceapplicationrunner.h>
|
||||||
|
#include <projectexplorer/profileinformation.h>
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
@@ -42,120 +45,112 @@ using namespace ProjectExplorer;
|
|||||||
|
|
||||||
namespace RemoteLinux {
|
namespace RemoteLinux {
|
||||||
|
|
||||||
using ProjectExplorer::RunConfiguration;
|
class RemoteLinuxRunControl::RemoteLinuxRunControlPrivate
|
||||||
|
|
||||||
AbstractRemoteLinuxRunControl::AbstractRemoteLinuxRunControl(RunConfiguration *rc)
|
|
||||||
: RunControl(rc, ProjectExplorer::NormalRunMode)
|
|
||||||
, m_running(false)
|
|
||||||
{
|
{
|
||||||
}
|
public:
|
||||||
|
bool running;
|
||||||
|
ProjectExplorer::DeviceApplicationRunner runner;
|
||||||
|
IDevice::ConstPtr device;
|
||||||
|
QString remoteExecutable;
|
||||||
|
QString arguments;
|
||||||
|
QString prefix;
|
||||||
|
QByteArray stopCommand;
|
||||||
|
};
|
||||||
|
|
||||||
AbstractRemoteLinuxRunControl::~AbstractRemoteLinuxRunControl()
|
RemoteLinuxRunControl::RemoteLinuxRunControl(RunConfiguration *rc)
|
||||||
{
|
: RunControl(rc, ProjectExplorer::NormalRunMode), d(new RemoteLinuxRunControlPrivate)
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxRunControl::start()
|
|
||||||
{
|
|
||||||
m_running = true;
|
|
||||||
emit started();
|
|
||||||
disconnect(runner(), 0, this, 0);
|
|
||||||
connect(runner(), SIGNAL(error(QString)), SLOT(handleSshError(QString)));
|
|
||||||
connect(runner(), SIGNAL(readyForExecution()), SLOT(startExecution()));
|
|
||||||
connect(runner(), SIGNAL(remoteErrorOutput(QByteArray)),
|
|
||||||
SLOT(handleRemoteErrorOutput(QByteArray)));
|
|
||||||
connect(runner(), SIGNAL(remoteOutput(QByteArray)),
|
|
||||||
SLOT(handleRemoteOutput(QByteArray)));
|
|
||||||
connect(runner(), SIGNAL(remoteProcessStarted()),
|
|
||||||
SLOT(handleRemoteProcessStarted()));
|
|
||||||
connect(runner(), SIGNAL(remoteProcessFinished(qint64)),
|
|
||||||
SLOT(handleRemoteProcessFinished(qint64)));
|
|
||||||
connect(runner(), SIGNAL(reportProgress(QString)),
|
|
||||||
SLOT(handleProgressReport(QString)));
|
|
||||||
runner()->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
RunControl::StopResult AbstractRemoteLinuxRunControl::stop()
|
|
||||||
{
|
|
||||||
runner()->stop();
|
|
||||||
return AsynchronousStop;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxRunControl::handleSshError(const QString &error)
|
|
||||||
{
|
|
||||||
handleError(error);
|
|
||||||
setFinished();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxRunControl::startExecution()
|
|
||||||
{
|
|
||||||
appendMessage(tr("Starting remote process...\n"), Utils::NormalMessageFormat);
|
|
||||||
runner()->startExecution(QString::fromLatin1("%1 %2 %3")
|
|
||||||
.arg(runner()->commandPrefix())
|
|
||||||
.arg(runner()->remoteExecutable())
|
|
||||||
.arg(runner()->arguments()).toUtf8());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxRunControl::handleRemoteProcessFinished(qint64 exitCode)
|
|
||||||
{
|
|
||||||
if (exitCode != AbstractRemoteLinuxApplicationRunner::InvalidExitCode) {
|
|
||||||
appendMessage(tr("Finished running remote process. Exit code was %1.\n")
|
|
||||||
.arg(exitCode), Utils::NormalMessageFormat);
|
|
||||||
}
|
|
||||||
setFinished();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxRunControl::handleRemoteOutput(const QByteArray &output)
|
|
||||||
{
|
|
||||||
appendMessage(QString::fromUtf8(output), Utils::StdOutFormatSameLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxRunControl::handleRemoteErrorOutput(const QByteArray &output)
|
|
||||||
{
|
|
||||||
appendMessage(QString::fromUtf8(output), Utils::StdErrFormatSameLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxRunControl::handleProgressReport(const QString &progressString)
|
|
||||||
{
|
|
||||||
appendMessage(progressString + QLatin1Char('\n'), Utils::NormalMessageFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AbstractRemoteLinuxRunControl::isRunning() const
|
|
||||||
{
|
|
||||||
return m_running;
|
|
||||||
}
|
|
||||||
|
|
||||||
QIcon AbstractRemoteLinuxRunControl::icon() const
|
|
||||||
{
|
|
||||||
return QIcon(ProjectExplorer::Constants::ICON_RUN_SMALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxRunControl::handleError(const QString &errString)
|
|
||||||
{
|
|
||||||
stop();
|
|
||||||
appendMessage(errString, Utils::ErrorMessageFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRemoteLinuxRunControl::setFinished()
|
|
||||||
{
|
|
||||||
disconnect(runner(), 0, this, 0);
|
|
||||||
m_running = false;
|
|
||||||
emit finished();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RemoteLinuxRunControl::RemoteLinuxRunControl(ProjectExplorer::RunConfiguration *runConfig)
|
|
||||||
: AbstractRemoteLinuxRunControl(runConfig),
|
|
||||||
m_runner(new GenericRemoteLinuxApplicationRunner(qobject_cast<RemoteLinuxRunConfiguration *>(runConfig), this))
|
|
||||||
{
|
{
|
||||||
|
d->running = false;
|
||||||
|
d->device = DeviceProfileInformation::device(rc->target()->profile());
|
||||||
|
const RemoteLinuxRunConfiguration * const lrc = qobject_cast<RemoteLinuxRunConfiguration *>(rc);
|
||||||
|
d->remoteExecutable = lrc->remoteExecutableFilePath();
|
||||||
|
d->arguments = lrc->arguments();
|
||||||
|
d->prefix = lrc->commandPrefix();
|
||||||
|
d->stopCommand = RemoteLinuxUtils::killApplicationCommandLine(d->remoteExecutable).toUtf8();
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteLinuxRunControl::~RemoteLinuxRunControl()
|
RemoteLinuxRunControl::~RemoteLinuxRunControl()
|
||||||
{
|
{
|
||||||
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractRemoteLinuxApplicationRunner *RemoteLinuxRunControl::runner() const
|
void RemoteLinuxRunControl::start()
|
||||||
{
|
{
|
||||||
return m_runner;
|
d->running = true;
|
||||||
|
emit started();
|
||||||
|
d->runner.disconnect(this);
|
||||||
|
connect(&d->runner, SIGNAL(reportError(QString)), SLOT(handleErrorMessage(QString)));
|
||||||
|
connect(&d->runner, SIGNAL(remoteStderr(QByteArray)),
|
||||||
|
SLOT(handleRemoteErrorOutput(QByteArray)));
|
||||||
|
connect(&d->runner, SIGNAL(remoteStdout(QByteArray)), SLOT(handleRemoteOutput(QByteArray)));
|
||||||
|
connect(&d->runner, SIGNAL(finished(bool)), SLOT(handleRunnerFinished()));
|
||||||
|
connect(&d->runner, SIGNAL(reportProgress(QString)), SLOT(handleProgressReport(QString)));
|
||||||
|
const QString commandLine = QString::fromLatin1("%1 %2 %3")
|
||||||
|
.arg(d->prefix, d->remoteExecutable, d->arguments);
|
||||||
|
d->runner.start(d->device, commandLine.toUtf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
RunControl::StopResult RemoteLinuxRunControl::stop()
|
||||||
|
{
|
||||||
|
d->runner.stop(d->stopCommand);
|
||||||
|
return AsynchronousStop;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteLinuxRunControl::handleErrorMessage(const QString &error)
|
||||||
|
{
|
||||||
|
appendMessage(error, Utils::ErrorMessageFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteLinuxRunControl::handleRunnerFinished()
|
||||||
|
{
|
||||||
|
setFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteLinuxRunControl::handleRemoteOutput(const QByteArray &output)
|
||||||
|
{
|
||||||
|
appendMessage(QString::fromUtf8(output), Utils::StdOutFormatSameLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteLinuxRunControl::handleRemoteErrorOutput(const QByteArray &output)
|
||||||
|
{
|
||||||
|
appendMessage(QString::fromUtf8(output), Utils::StdErrFormatSameLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteLinuxRunControl::handleProgressReport(const QString &progressString)
|
||||||
|
{
|
||||||
|
appendMessage(progressString + QLatin1Char('\n'), Utils::NormalMessageFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RemoteLinuxRunControl::isRunning() const
|
||||||
|
{
|
||||||
|
return d->running;
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon RemoteLinuxRunControl::icon() const
|
||||||
|
{
|
||||||
|
return QIcon(ProjectExplorer::Constants::ICON_RUN_SMALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteLinuxRunControl::setApplicationRunnerPreRunAction(DeviceApplicationHelperAction *action)
|
||||||
|
{
|
||||||
|
d->runner.setPreRunAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteLinuxRunControl::setApplicationRunnerPostRunAction(DeviceApplicationHelperAction *action)
|
||||||
|
{
|
||||||
|
d->runner.setPostRunAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteLinuxRunControl::overrideStopCommandLine(const QByteArray &commandLine)
|
||||||
|
{
|
||||||
|
d->stopCommand = commandLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteLinuxRunControl::setFinished()
|
||||||
|
{
|
||||||
|
d->runner.disconnect(this);
|
||||||
|
d->running = false;
|
||||||
|
emit finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace RemoteLinux
|
} // namespace RemoteLinux
|
||||||
|
@@ -34,54 +34,38 @@
|
|||||||
|
|
||||||
#include <projectexplorer/runconfiguration.h>
|
#include <projectexplorer/runconfiguration.h>
|
||||||
|
|
||||||
QT_FORWARD_DECLARE_CLASS(QString)
|
namespace ProjectExplorer { class DeviceApplicationHelperAction; }
|
||||||
|
|
||||||
namespace RemoteLinux {
|
namespace RemoteLinux {
|
||||||
class AbstractRemoteLinuxApplicationRunner;
|
|
||||||
|
|
||||||
class REMOTELINUX_EXPORT AbstractRemoteLinuxRunControl : public ProjectExplorer::RunControl
|
class REMOTELINUX_EXPORT RemoteLinuxRunControl : public ProjectExplorer::RunControl
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_DISABLE_COPY(AbstractRemoteLinuxRunControl)
|
|
||||||
public:
|
public:
|
||||||
explicit AbstractRemoteLinuxRunControl(ProjectExplorer::RunConfiguration *runConfig);
|
explicit RemoteLinuxRunControl(ProjectExplorer::RunConfiguration *runConfig);
|
||||||
virtual ~AbstractRemoteLinuxRunControl();
|
virtual ~RemoteLinuxRunControl();
|
||||||
|
|
||||||
virtual void start();
|
virtual void start();
|
||||||
virtual StopResult stop();
|
virtual StopResult stop();
|
||||||
virtual bool isRunning() const;
|
virtual bool isRunning() const;
|
||||||
virtual QIcon icon() const;
|
virtual QIcon icon() const;
|
||||||
|
|
||||||
virtual AbstractRemoteLinuxApplicationRunner *runner() const = 0;
|
void setApplicationRunnerPreRunAction(ProjectExplorer::DeviceApplicationHelperAction *action);
|
||||||
|
void setApplicationRunnerPostRunAction(ProjectExplorer::DeviceApplicationHelperAction *action);
|
||||||
|
void overrideStopCommandLine(const QByteArray &commandLine);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void startExecution();
|
void handleErrorMessage(const QString &error);
|
||||||
void handleSshError(const QString &error);
|
void handleRunnerFinished();
|
||||||
void handleRemoteProcessStarted() {}
|
|
||||||
void handleRemoteProcessFinished(qint64 exitCode);
|
|
||||||
void handleRemoteOutput(const QByteArray &output);
|
void handleRemoteOutput(const QByteArray &output);
|
||||||
void handleRemoteErrorOutput(const QByteArray &output);
|
void handleRemoteErrorOutput(const QByteArray &output);
|
||||||
void handleProgressReport(const QString &progressString);
|
void handleProgressReport(const QString &progressString);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setFinished();
|
void setFinished();
|
||||||
void handleError(const QString &errString);
|
|
||||||
|
|
||||||
bool m_running;
|
class RemoteLinuxRunControlPrivate;
|
||||||
};
|
RemoteLinuxRunControlPrivate * const d;
|
||||||
|
|
||||||
|
|
||||||
class REMOTELINUX_EXPORT RemoteLinuxRunControl : public AbstractRemoteLinuxRunControl
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit RemoteLinuxRunControl(ProjectExplorer::RunConfiguration *runConfig);
|
|
||||||
virtual ~RemoteLinuxRunControl();
|
|
||||||
private:
|
|
||||||
virtual AbstractRemoteLinuxApplicationRunner *runner() const;
|
|
||||||
|
|
||||||
AbstractRemoteLinuxApplicationRunner * const m_runner;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace RemoteLinux
|
} // namespace RemoteLinux
|
||||||
|
@@ -89,14 +89,14 @@ RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Ru
|
|||||||
if (mode == ProjectExplorer::NormalRunMode)
|
if (mode == ProjectExplorer::NormalRunMode)
|
||||||
return new RemoteLinuxRunControl(rc);
|
return new RemoteLinuxRunControl(rc);
|
||||||
|
|
||||||
DebuggerStartParameters params = AbstractRemoteLinuxDebugSupport::startParameters(rc);
|
DebuggerStartParameters params = LinuxDeviceDebugSupport::startParameters(rc);
|
||||||
if (mode == ProjectExplorer::DebugRunModeWithBreakOnMain)
|
if (mode == ProjectExplorer::DebugRunModeWithBreakOnMain)
|
||||||
params.breakOnMain = true;
|
params.breakOnMain = true;
|
||||||
DebuggerRunControl * const runControl = DebuggerPlugin::createDebugger(params, rc);
|
DebuggerRunControl * const runControl = DebuggerPlugin::createDebugger(params, rc);
|
||||||
if (!runControl)
|
if (!runControl)
|
||||||
return 0;
|
return 0;
|
||||||
RemoteLinuxDebugSupport *debugSupport =
|
LinuxDeviceDebugSupport * const debugSupport =
|
||||||
new RemoteLinuxDebugSupport(rc, runControl->engine());
|
new LinuxDeviceDebugSupport(rc, runControl->engine());
|
||||||
connect(runControl, SIGNAL(finished()), debugSupport, SLOT(handleDebuggingFinished()));
|
connect(runControl, SIGNAL(finished()), debugSupport, SLOT(handleDebuggingFinished()));
|
||||||
return runControl;
|
return runControl;
|
||||||
}
|
}
|
||||||
|
@@ -41,9 +41,14 @@ using namespace ExtensionSystem;
|
|||||||
|
|
||||||
namespace RemoteLinux {
|
namespace RemoteLinux {
|
||||||
|
|
||||||
QString RemoteLinuxUtils::deviceConfigurationName(const LinuxDeviceConfiguration::ConstPtr &devConf)
|
QString RemoteLinuxUtils::killApplicationCommandLine(const QString &applicationFilePath)
|
||||||
{
|
{
|
||||||
return devConf ? devConf->displayName() : QCoreApplication::translate("RemoteLinux", "(No device)");
|
return QString::fromLatin1("cd /proc; for pid in `ls -d [0123456789]*`; "
|
||||||
|
"do "
|
||||||
|
"if [ \"`readlink /proc/$pid/exe`\" = \"%1\" ]; then "
|
||||||
|
" kill $pid; sleep 1; kill -9 $pid; "
|
||||||
|
"fi; "
|
||||||
|
"done").arg(applicationFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace RemoteLinux
|
} // namespace RemoteLinux
|
||||||
|
@@ -40,7 +40,7 @@ class LinuxDeviceConfiguration;
|
|||||||
class REMOTELINUX_EXPORT RemoteLinuxUtils
|
class REMOTELINUX_EXPORT RemoteLinuxUtils
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static QString deviceConfigurationName(const QSharedPointer<const LinuxDeviceConfiguration> &devConf);
|
static QString killApplicationCommandLine(const QString &applicationFilePath);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace RemoteLinux
|
} // namespace RemoteLinux
|
||||||
|
Reference in New Issue
Block a user