RemoteLinux: Don't assume a POSIX-compliant ps command.

Presumably, lots of embedded systems don't have one.

Task-number: QTCREATORBUG-5918
Change-Id: Idfbd7fe2d27ed992b3f3dbba240943d0fe41dc5b
Reviewed-on: http://codereview.qt-project.org/4432
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Christian Kandeler <christian.kandeler@nokia.com>
This commit is contained in:
Christian Kandeler
2011-09-08 12:38:46 +02:00
parent bfc95befa8
commit 2db7393234
5 changed files with 35 additions and 156 deletions

View File

@@ -35,10 +35,10 @@
#include "maemoconstants.h"
#include "maemodeviceconfigwizard.h"
#include "publickeydeploymentdialog.h"
#include "madderemoteprocesslist.h"
#include <remotelinux/linuxdevicetestdialog.h>
#include <remotelinux/remotelinuxprocessesdialog.h>
#include <remotelinux/remotelinuxprocesslist.h>
#include <remotelinux/remotelinux_constants.h>
#include <utils/qtcassert.h>
@@ -108,7 +108,7 @@ QDialog *MaddeDeviceConfigurationFactory::createDeviceAction(const QString &acti
if (actionId == QLatin1String(MaddeDeviceTestActionId))
return new LinuxDeviceTestDialog(deviceConfig, new MaddeDeviceTester, parent);
if (actionId == QLatin1String(MaddeRemoteProcessesActionId))
return new RemoteLinuxProcessesDialog(new MaddeRemoteProcessList(deviceConfig), parent);
return new RemoteLinuxProcessesDialog(new GenericRemoteLinuxProcessList(deviceConfig), parent);
if (actionId == QLatin1String(Constants::GenericDeployKeyToDeviceActionId))
return new PublicKeyDeploymentDialog(deviceConfig, parent);
return 0; // Can't happen.

View File

@@ -1,85 +0,0 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.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 "madderemoteprocesslist.h"
#include "maemoconstants.h"
#include <remotelinux/linuxdeviceconfiguration.h>
#include <QtCore/QString>
namespace RemoteLinux {
namespace Internal {
namespace {
const char FremantleLineSeparator1[] = "---";
const char FremantleLineSeparator2[] = "QTCENDOFLINE---";
} // anonymous namespace
MaddeRemoteProcessList::MaddeRemoteProcessList(const LinuxDeviceConfiguration::ConstPtr &devConfig,
QObject *parent) : GenericRemoteLinuxProcessList(devConfig, parent)
{
}
QString MaddeRemoteProcessList::listProcessesCommandLine() const
{
// The ps command on Fremantle ignores all command line options, so
// we have to collect the information in /proc manually.
if (deviceConfiguration()->osType() == QLatin1String(Maemo5OsType)) {
return QLatin1String("sep1=") + QLatin1String(FremantleLineSeparator1) + QLatin1Char(';')
+ QLatin1String("sep2=") + QLatin1String(FremantleLineSeparator2) + QLatin1Char(';')
+ QLatin1String("pidlist=`ls /proc |grep -E '^[[:digit:]]+$' |sort -n`; "
"for pid in $pidlist;"
"do "
" echo -n \"$pid \";"
" tr '\\0' ' ' < /proc/$pid/cmdline;"
" echo -n \"$sep1$sep2\";"
"done;"
"echo ''");
}
return GenericRemoteLinuxProcessList::listProcessesCommandLine();
}
QList<AbstractRemoteLinuxProcessList::RemoteProcess> MaddeRemoteProcessList::buildProcessList(const QString &listProcessesReply) const
{
QString adaptedReply = listProcessesReply;
if (deviceConfiguration()->osType() == QLatin1String(Maemo5OsType)) {
adaptedReply.replace(QLatin1String(FremantleLineSeparator1)
+ QLatin1String(FremantleLineSeparator2), QLatin1String("\n"));
adaptedReply.prepend(QLatin1String("dummy\n"));
}
return GenericRemoteLinuxProcessList::buildProcessList(adaptedReply);
}
} // namespace Internal
} // namespace RemoteLinux

View File

@@ -1,54 +0,0 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.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 MADDEREMOTEPROCESSLIST_H
#define MADDEREMOTEPROCESSLIST_H
#include <remotelinux/remotelinuxprocesslist.h>
namespace RemoteLinux {
namespace Internal {
class MaddeRemoteProcessList : public RemoteLinux::GenericRemoteLinuxProcessList
{
Q_OBJECT
public:
MaddeRemoteProcessList(const QSharedPointer<const LinuxDeviceConfiguration> &devConfig,
QObject *parent = 0);
private:
QString listProcessesCommandLine() const;
QList<RemoteProcess> buildProcessList(const QString &listProcessesReply) const;
};
} // namespace Internal
} // namespace RemoteLinux
#endif // MADDEREMOTEPROCESSLIST_H

View File

@@ -87,7 +87,6 @@ HEADERS += \
remotelinux_constants.h \
linuxdevicetestdialog.h \
remotelinuxprocesslist.h \
madderemoteprocesslist.h \
remotelinuxprocessesdialog.h \
remotelinuxdeploystepwidget.h \
linuxdeviceconfigurationssettingswidget.h \
@@ -180,7 +179,6 @@ SOURCES += \
maddedevicetester.cpp \
linuxdevicetestdialog.cpp \
remotelinuxprocesslist.cpp \
madderemoteprocesslist.cpp \
remotelinuxprocessesdialog.cpp \
remotelinuxdeploystepwidget.cpp \
linuxdeviceconfigurationssettingswidget.cpp \
@@ -220,3 +218,5 @@ FORMS += \
RESOURCES += qt-maemo.qrc
DEFINES += QT_NO_CAST_TO_ASCII
DEFINES += REMOTELINUX_LIBRARY

View File

@@ -44,6 +44,7 @@ namespace RemoteLinux {
namespace Internal {
namespace {
enum State { Inactive, Listing, Killing };
const char Delimiter[] = "-----";
} // anonymous namespace
class AbstractRemoteLinuxProcessListPrivate
@@ -225,7 +226,8 @@ GenericRemoteLinuxProcessList::GenericRemoteLinuxProcessList(const LinuxDeviceCo
QString GenericRemoteLinuxProcessList::listProcessesCommandLine() const
{
return QLatin1String("ps -eo pid,args");
return QString::fromLocal8Bit("for dir in `ls -d /proc/[0123456789]*`; "
"do echo $dir%1`cat $dir/cmdline`%1`cat $dir/stat`; done").arg(Delimiter);
}
QString GenericRemoteLinuxProcessList::killProcessCommandLine(const RemoteProcess &process) const
@@ -236,21 +238,37 @@ QString GenericRemoteLinuxProcessList::killProcessCommandLine(const RemoteProces
QList<AbstractRemoteLinuxProcessList::RemoteProcess> GenericRemoteLinuxProcessList::buildProcessList(const QString &listProcessesReply) const
{
QList<RemoteProcess> processes;
QStringList lines = listProcessesReply.split(QLatin1Char('\n'));
lines.removeFirst(); // column headers
const QStringList &lines = listProcessesReply.split(QLatin1Char('\n'));
foreach (const QString &line, lines) {
const QString &trimmedLine = line.trimmed();
const int pidEndPos = trimmedLine.indexOf(QLatin1Char(' '));
if (pidEndPos == -1)
continue;
bool isNumber;
const int pid = trimmedLine.left(pidEndPos).toInt(&isNumber);
if (!isNumber) {
qDebug("%s: Non-integer value where pid was expected. Line was: '%s'",
Q_FUNC_INFO, qPrintable(trimmedLine));
const QStringList elements = line.split(QString::fromLocal8Bit(Delimiter));
if (elements.count() < 3) {
qDebug("%s: Expected three list elements, got %d.", Q_FUNC_INFO, elements.count());
continue;
}
processes << RemoteProcess(pid, trimmedLine.mid(pidEndPos));
bool ok;
const int pid = elements.first().mid(6).toInt(&ok);
if (!ok) {
qDebug("%s: Expected number in %s.", Q_FUNC_INFO, qPrintable(elements.first()));
continue;
}
QString command = elements.at(1);
if (command.isEmpty()) {
const QString &statString = elements.at(2);
const int openParenPos = statString.indexOf(QLatin1Char('('));
const int closedParenPos = statString.indexOf(QLatin1Char(')'), openParenPos);
if (openParenPos == -1 || closedParenPos == -1)
continue;
command = QLatin1Char('[')
+ statString.mid(openParenPos + 1, closedParenPos - openParenPos - 1)
+ QLatin1Char(']');
}
int insertPos;
for (insertPos = 0; insertPos < processes.count(); ++insertPos) {
if (pid < processes.at(insertPos).pid)
break;
}
processes.insert(insertPos, RemoteProcess(pid, command));
}
return processes;