/guitone-1.0rc5/src/monotone/MonotoneProcess.cpp
C++ | 199 lines | 143 code | 34 blank | 22 comment | 15 complexity | f06aa6a9da355fdf2cd2e1150f3edb4c MD5 | raw file
Possible License(s): GPL-3.0
- /***************************************************************************
- * Copyright (C) 2010 by Thomas Keller *
- * me@thomaskeller.biz *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
- #include "MonotoneProcess.h"
- #include "MonotoneUtil.h"
- #include "Settings.h"
- #include "vocab.h"
- #include <QDir>
- MonotoneProcess::MonotoneProcess()
- {
- setProcessChannelMode(QProcess::MergedChannels);
- QStringList env = QProcess::systemEnvironment();
- env.replaceInStrings(QRegExp("^LANG=.*", Qt::CaseInsensitive), "");
- env.push_back("LANG=en_US.UTF-8");
- setEnvironment(env);
- connect(
- this, SIGNAL(readyReadStandardOutput()),
- this, SLOT(readOutput())
- );
- connect(
- this, SIGNAL(readyReadStandardError()),
- this, SLOT(readOutput())
- );
- connect(
- this, SIGNAL(error(QProcess::ProcessError)),
- this, SLOT(processError(QProcess::ProcessError))
- );
- }
- MonotoneProcess::~MonotoneProcess()
- {
- if (state() != NotRunning)
- {
- close();
- terminate();
- waitForFinished();
- }
- }
- void MonotoneProcess::setMonotoneBinaryPath(const QString & path)
- {
- monotoneBinaryPath = path;
- }
- void MonotoneProcess::setMonotoneHandle(const MonotoneHandlePtr & handle)
- {
- I(handle->getType() != MonotoneHandle::server_handle);
- monotoneHandle = handle;
- }
- void MonotoneProcess::start(const QStringList & params)
- {
- bufferedOutput = QString();
- if (monotoneBinaryPath.isEmpty())
- {
- monotoneBinaryPath = Settings::getString("MtnExePath");
- }
- QStringList finalParams;
- if (!Settings::getBool("ReadUserRcFiles"))
- {
- finalParams << "--no-standard-rcfiles";
- }
- finalParams << "--rcfile" << rcFile.fileName();
- if (monotoneHandle.isNull())
- {
- monotoneHandle = MonotoneHandle::create();
- }
- // a somewhat reasonable path to choose to avoid side effects
- // like another existing monotone workspace
- QString workingDir = QDir::tempPath();
- if (monotoneHandle->getType() == MonotoneHandle::workspace_handle)
- {
- workingDir = monotoneHandle->getData();
- }
- setWorkingDirectory(workingDir);
- if (monotoneHandle->getType() == MonotoneHandle::database_handle)
- {
- finalParams << "-d" << monotoneHandle->getData();
- }
- finalParams += params;
- L(QString("starting external monotone process %1 %2")
- .arg(monotoneBinaryPath).arg(finalParams.join(" ")));
- QProcess::start(monotoneBinaryPath, finalParams);
- }
- void MonotoneProcess::readOutput()
- {
- QByteArray out = readAll();
- if (out.isEmpty()) return;
- QString strOut = QString::fromUtf8(out);
- emit output(strOut);
- bufferedOutput += strOut;
- }
- QString MonotoneProcess::getBufferedOutput() const
- {
- return bufferedOutput;
- }
- void MonotoneProcess::processError(QProcess::ProcessError processError)
- {
- QString message = QString::fromUtf8(readAllStandardError());
- // what follows is largely copied from MonotoneManager::abort
- QString mtnError = MonotoneUtil::stripMtnPrefix(message);
- QString processErrorTranslated;
- switch (processError)
- {
- case QProcess::FailedToStart:
- processErrorTranslated = tr("failed to start");
- break;
- case QProcess::Crashed:
- processErrorTranslated = tr("crashed");
- break;
- case QProcess::Timedout:
- processErrorTranslated = tr("timed out waiting for data");
- break;
- case QProcess::WriteError:
- processErrorTranslated = tr("failed to read");
- break;
- case QProcess::ReadError:
- processErrorTranslated = tr("failed to write");
- break;
- case QProcess::UnknownError:
- processErrorTranslated = tr("unknown error");
- break;
- default: I(false);
- }
- // log something reasonable
- C(QString("process died (%1) - stderr was %2")
- .arg(processErrorTranslated).arg(mtnError));
- // display something understandable to the user
- QString userMessage(tr(
- "The monotone process for '%1' died (%2). "
- "If you think this is a bug in guitone, "
- "please report it to the author!"
- ).arg(workingDirectory()).arg(processErrorTranslated));
- if (!mtnError.isEmpty())
- {
- userMessage.append(tr("\n\nLast error output was:\n%1").arg(mtnError));
- }
- emit error(userMessage);
- }
- bool MonotoneProcess::successful()
- {
- return exitStatus() == QProcess::NormalExit &&
- exitCode() == 0;
- }
- bool MonotoneProcess::singleRun(const QStringList & params,
- const MonotoneHandlePtr & handle,
- QString & output)
- {
- MonotoneProcess proc;
- proc.setMonotoneHandle(handle);
- proc.start(params);
- proc.waitForFinished();
- output = proc.getBufferedOutput();
- return proc.successful();
- }