From de9b2035655a0a9be4ad789f6a378c4b3e1fde51 Mon Sep 17 00:00:00 2001 From: ck Date: Fri, 16 Apr 2010 12:15:08 +0200 Subject: [PATCH] Maemo: Filter remote output. Reviewed-by: kh1 --- .../qt-maemo/maemoruncontrol.cpp | 4 +- .../qt-maemo/maemosshconnection.cpp | 79 ++++++++++++++++--- .../qt-maemo/maemosshconnection.h | 2 +- 3 files changed, 69 insertions(+), 16 deletions(-) diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp index 4a6d31afdfc..5a80bdee0e4 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp @@ -239,8 +239,8 @@ void AbstractMaemoRunControl::killRemoteProcesses(const QStringList &apps, niceKill += QString::fromLocal8Bit("pkill -x %1;").arg(app); brutalKill += QString::fromLocal8Bit("pkill -x -9 %1;").arg(app); } - const QString remoteCall - = niceKill + QLatin1String("sleep 1; ") + brutalKill; + QString remoteCall = niceKill + QLatin1String("sleep 1; ") + brutalKill; + remoteCall.remove(remoteCall.count() - 1, 1); // Get rid of trailing semicolon. QScopedPointer &runner = initialCleanup ? m_initialCleaner : m_sshStopper; runner.reset(new MaemoSshRunner(m_devConfig, remoteCall)); diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemosshconnection.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemosshconnection.cpp index 59c1e878d24..9a15a4a5fad 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemosshconnection.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemosshconnection.cpp @@ -102,13 +102,20 @@ void MaemoSshConnection::stop() } MaemoInteractiveSshConnection::MaemoInteractiveSshConnection(const MaemoDeviceConfig &devConf) - : MaemoSshConnection(devConf, true), m_prompt(0) + : MaemoSshConnection(devConf, true) { - m_prompt = devConf.uname == QLatin1String("root") ? "# " : "$ "; + strcpy(m_prompt, devConf.uname == QLatin1String("root") ? "# " : "$ "); if (!ssh->waitFor(channel(), m_prompt, devConf.timeout)) { - const QString error - = tr("Could not start remote shell: %1").arg(lastError()); - throw MaemoSshException(error); + QScopedPointer > + shellString(ssh->readAndReset(channel(), alloc)); + if (!shellString.data()) { + const QString error + = tr("Could not start remote shell: %1").arg(lastError()); + throw MaemoSshException(error); + } else { + const int length = strlen(shellString.data()); + strcpy(m_prompt, shellString.data() + length - qMin(2, length)); + } } } @@ -120,26 +127,72 @@ MaemoInteractiveSshConnection::~MaemoInteractiveSshConnection() void MaemoInteractiveSshConnection::runCommand(const QString &command) { - if (!ssh->send((command + QLatin1String("\n")).toLatin1().data(), - channel())) { + /* + * We don't have access to the remote process management, so we + * try to track the lifetime of the process by adding a second command + * that prints a rare character. When it occurs for the second time (the + * first one is the echo from the remote terminal), we assume the + * process has finished. If anyone actually prints this special character + * in their application, they are out of luck. + */ + const QString endMarker(QChar(0x13a0)); + const int endMarkerLen = strlen(endMarker.toUtf8()); + + const QString finalCommand + = command + QLatin1String(";echo ") + endMarker + QLatin1Char('\n'); + if (!ssh->send(finalCommand.toUtf8().data(), channel())) { throw MaemoSshException(tr("Error running command: %1") .arg(lastError())); } - bool done; + int endMarkerCount = 0; do { - done = ssh->waitFor(channel(), m_prompt, 1); + ssh->waitFor(channel(), endMarker.toUtf8(), 1); const char * const error = lastError(); if (error) throw MaemoSshException(tr("SSH error: %1").arg(error)); QScopedPointer > output(ssh->readAndReset(channel(), alloc)); + + /* + * The output the user should see is everything after the first + * and before the last occurrence of our marker string. + */ if (output.data()) { - emit remoteOutput(QString::fromUtf8(output.data())); - if (!done) - done = strstr(output.data(), m_prompt) != 0; + const char *firstCharToEmit; + int charsToEmitCount; + const char * const endMarkerPos + = strstr(output.data(), endMarker.toUtf8()); + if (endMarkerPos) { + if (endMarkerCount++ == 0) { + emit remoteOutput(QLatin1String("========== Remote output starts now. ==========")); + firstCharToEmit = endMarkerPos + endMarkerLen + 1; + const char * const endMarkerPos2 + = strstr(firstCharToEmit, endMarker.toUtf8()); + if (endMarkerPos2) { + ++ endMarkerCount; + charsToEmitCount = endMarkerPos2 - firstCharToEmit; + } else { + charsToEmitCount = -1; + } + } else { + firstCharToEmit = output.data(); + charsToEmitCount = endMarkerPos - output.data(); + } + } else { + if (endMarkerCount == 0) { + charsToEmitCount = 0; + } else { + firstCharToEmit = output.data(); + charsToEmitCount = -1; + } + } + + if (charsToEmitCount != 0) + emit remoteOutput(QString::fromUtf8(firstCharToEmit, charsToEmitCount)); } - } while (!done && !stopRequested()); + } while (endMarkerCount < 2 && !stopRequested()); + emit remoteOutput(QLatin1String("========== Remote output ends now. ==========")); } MaemoInteractiveSshConnection::Ptr MaemoInteractiveSshConnection::create(const MaemoDeviceConfig &devConf) diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemosshconnection.h b/src/plugins/qt4projectmanager/qt-maemo/maemosshconnection.h index ef9b5f8c216..6b46d568092 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemosshconnection.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemosshconnection.h @@ -103,7 +103,7 @@ signals: private: MaemoInteractiveSshConnection(const MaemoDeviceConfig &devConf); - const char *m_prompt; + char m_prompt[3]; };