forked from qt-creator/qt-creator
Utils: Add a QString-based write to QtcProcess
Centralize some boiler plate and warn about best-guessed cases. Keep the QByteArray based access as writeRaw() Fixes: QTCREATORBUG-27445 Change-Id: I948d80fba78b36cf85cc73664175ab05eb7707d4 Reviewed-by: Orgad Shaneh <orgads@gmail.com> Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
@@ -1207,11 +1207,27 @@ QByteArray QtcProcess::readAllStandardError()
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 QtcProcess::write(const QByteArray &input)
|
qint64 QtcProcess::write(const QString &input)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(processMode() == ProcessMode::Writer, return -1);
|
QTC_ASSERT(processMode() == ProcessMode::Writer, return -1);
|
||||||
QTC_ASSERT(d->m_process, return -1);
|
QTC_ASSERT(d->m_process, return -1);
|
||||||
QTC_ASSERT(state() == QProcess::Running, return -1);
|
QTC_ASSERT(state() == QProcess::Running, return -1);
|
||||||
|
|
||||||
|
// Non-windows is assumed to be UTF-8
|
||||||
|
if (commandLine().executable().osType() != OsTypeWindows)
|
||||||
|
return writeRaw(input.toUtf8());
|
||||||
|
|
||||||
|
if (HostOsInfo::hostOs() == OsTypeWindows)
|
||||||
|
return writeRaw(input.toLocal8Bit());
|
||||||
|
|
||||||
|
// "remote" Windows target on non-Windows host is unlikely,
|
||||||
|
// but the true encoding is not accessible. Use UTF8 as best guess.
|
||||||
|
QTC_CHECK(false);
|
||||||
|
return writeRaw(input.toUtf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 QtcProcess::writeRaw(const QByteArray &input)
|
||||||
|
{
|
||||||
return d->m_process->write(input);
|
return d->m_process->write(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -69,7 +69,9 @@ public:
|
|||||||
|
|
||||||
virtual QByteArray readAllStandardOutput();
|
virtual QByteArray readAllStandardOutput();
|
||||||
virtual QByteArray readAllStandardError();
|
virtual QByteArray readAllStandardError();
|
||||||
virtual qint64 write(const QByteArray &input);
|
|
||||||
|
virtual qint64 write(const QString &input);
|
||||||
|
qint64 writeRaw(const QByteArray &input);
|
||||||
|
|
||||||
virtual qint64 processId() const;
|
virtual qint64 processId() const;
|
||||||
qint64 applicationMainThreadId() const;
|
qint64 applicationMainThreadId() const;
|
||||||
|
@@ -130,7 +130,7 @@ static CreateAvdInfo createAvdCommand(const AndroidConfig &config, const CreateA
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
QTC_CHECK(proc.isRunning());
|
QTC_CHECK(proc.isRunning());
|
||||||
proc.write(QByteArray("yes\n")); // yes to "Do you wish to create a custom hardware profile"
|
proc.write("yes\n"); // yes to "Do you wish to create a custom hardware profile"
|
||||||
|
|
||||||
auto start = chrono::steady_clock::now();
|
auto start = chrono::steady_clock::now();
|
||||||
QString errorOutput;
|
QString errorOutput;
|
||||||
@@ -144,9 +144,9 @@ static CreateAvdInfo createAvdCommand(const AndroidConfig &config, const CreateA
|
|||||||
if (index != -1)
|
if (index != -1)
|
||||||
question = question.mid(index);
|
question = question.mid(index);
|
||||||
if (question.contains("hw.gpu.enabled"))
|
if (question.contains("hw.gpu.enabled"))
|
||||||
proc.write(QByteArray("yes\n"));
|
proc.write("yes\n");
|
||||||
else
|
else
|
||||||
proc.write(QByteArray("\n"));
|
proc.write("\n");
|
||||||
question.clear();
|
question.clear();
|
||||||
}
|
}
|
||||||
// The exit code is always 0, so we need to check stderr
|
// The exit code is always 0, so we need to check stderr
|
||||||
|
@@ -1041,7 +1041,7 @@ void AndroidSdkManagerPrivate::getPendingLicense(SdkCmdFutureInterface &fi)
|
|||||||
QByteArray userInput = getUserInput();
|
QByteArray userInput = getUserInput();
|
||||||
if (!userInput.isEmpty()) {
|
if (!userInput.isEmpty()) {
|
||||||
clearUserInput();
|
clearUserInput();
|
||||||
licenseCommand.write(userInput);
|
licenseCommand.writeRaw(userInput);
|
||||||
++inputCounter;
|
++inputCounter;
|
||||||
if (steps != -1)
|
if (steps != -1)
|
||||||
fi.setProgressValue(qRound((inputCounter / (double)steps) * 100));
|
fi.setProgressValue(qRound((inputCounter / (double)steps) * 100));
|
||||||
|
@@ -1060,7 +1060,7 @@ void CdbEngine::runCommand(const DebuggerCommand &dbgCmd)
|
|||||||
qDebug("CdbEngine::postCommand: resulting command '%s'\n", qPrintable(fullCmd));
|
qDebug("CdbEngine::postCommand: resulting command '%s'\n", qPrintable(fullCmd));
|
||||||
}
|
}
|
||||||
showMessage(cmd, LogInput);
|
showMessage(cmd, LogInput);
|
||||||
m_process.write(fullCmd.toLocal8Bit());
|
m_process.write(fullCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::activateFrame(int index)
|
void CdbEngine::activateFrame(int index)
|
||||||
|
@@ -785,7 +785,7 @@ void GdbEngine::runCommand(const DebuggerCommand &command)
|
|||||||
.arg(token).arg(buffer));
|
.arg(token).arg(buffer));
|
||||||
QMetaObject::invokeMethod(this, [this, buffer] { handleResponse(buffer); });
|
QMetaObject::invokeMethod(this, [this, buffer] { handleResponse(buffer); });
|
||||||
} else {
|
} else {
|
||||||
m_gdbProc.write(cmd.function.toUtf8() + "\r\n");
|
m_gdbProc.write(cmd.function + "\r\n");
|
||||||
if (command.flags & NeedsFlush) {
|
if (command.flags & NeedsFlush) {
|
||||||
// We don't need the response or result here, just want to flush
|
// We don't need the response or result here, just want to flush
|
||||||
// anything that's still on the gdb side.
|
// anything that's still on the gdb side.
|
||||||
|
@@ -153,7 +153,7 @@ void LldbEngine::runCommand(const DebuggerCommand &command)
|
|||||||
}
|
}
|
||||||
showMessage(msg, LogInput);
|
showMessage(msg, LogInput);
|
||||||
m_commandForToken[currentToken()] = cmd;
|
m_commandForToken[currentToken()] = cmd;
|
||||||
executeCommand("script theDumper." + function.toUtf8());
|
executeCommand("script theDumper." + function);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::debugLastCommand()
|
void LldbEngine::debugLastCommand()
|
||||||
@@ -170,7 +170,7 @@ void LldbEngine::handleAttachedToCore()
|
|||||||
updateLocals();
|
updateLocals();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::executeCommand(const QByteArray &command)
|
void LldbEngine::executeCommand(const QString &command)
|
||||||
{
|
{
|
||||||
// For some reason, sometimes LLDB misses the first character of the next command on Windows
|
// For some reason, sometimes LLDB misses the first character of the next command on Windows
|
||||||
// if passing only 1 LF.
|
// if passing only 1 LF.
|
||||||
@@ -242,14 +242,13 @@ void LldbEngine::setupEngine()
|
|||||||
|
|
||||||
const DebuggerRunParameters &rp = runParameters();
|
const DebuggerRunParameters &rp = runParameters();
|
||||||
|
|
||||||
executeCommand("script sys.path.insert(1, '" + rp.dumperPath.path().toLocal8Bit() + "')");
|
executeCommand("script sys.path.insert(1, '" + rp.dumperPath.path() + "')");
|
||||||
// This triggers reportState("enginesetupok") or "enginesetupfailed":
|
// This triggers reportState("enginesetupok") or "enginesetupfailed":
|
||||||
executeCommand("script from lldbbridge import *");
|
executeCommand("script from lldbbridge import *");
|
||||||
|
|
||||||
QString commands = nativeStartupCommands();
|
QString commands = nativeStartupCommands();
|
||||||
if (!commands.isEmpty())
|
if (!commands.isEmpty())
|
||||||
executeCommand(commands.toLocal8Bit());
|
executeCommand(commands);
|
||||||
|
|
||||||
|
|
||||||
const QString path = debuggerSettings()->extraDumperFile.value();
|
const QString path = debuggerSettings()->extraDumperFile.value();
|
||||||
if (!path.isEmpty() && QFileInfo(path).isReadable()) {
|
if (!path.isEmpty() && QFileInfo(path).isReadable()) {
|
||||||
|
@@ -130,7 +130,7 @@ private:
|
|||||||
void runCommand(const DebuggerCommand &cmd) override;
|
void runCommand(const DebuggerCommand &cmd) override;
|
||||||
void debugLastCommand() override;
|
void debugLastCommand() override;
|
||||||
void handleAttachedToCore();
|
void handleAttachedToCore();
|
||||||
void executeCommand(const QByteArray &command);
|
void executeCommand(const QString &command);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DebuggerCommand m_lastDebuggableCommand;
|
DebuggerCommand m_lastDebuggableCommand;
|
||||||
|
@@ -86,7 +86,7 @@ void PdbEngine::postDirectCommand(const QString &command)
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(m_proc.isRunning(), notifyEngineIll());
|
QTC_ASSERT(m_proc.isRunning(), notifyEngineIll());
|
||||||
showMessage(command, LogInput);
|
showMessage(command, LogInput);
|
||||||
m_proc.write(command.toUtf8() + '\n');
|
m_proc.write(command + '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
void PdbEngine::runCommand(const DebuggerCommand &cmd)
|
void PdbEngine::runCommand(const DebuggerCommand &cmd)
|
||||||
@@ -98,7 +98,7 @@ void PdbEngine::runCommand(const DebuggerCommand &cmd)
|
|||||||
QTC_ASSERT(m_proc.isRunning(), notifyEngineIll());
|
QTC_ASSERT(m_proc.isRunning(), notifyEngineIll());
|
||||||
QString command = "qdebug('" + cmd.function + "'," + cmd.argsToPython() + ")";
|
QString command = "qdebug('" + cmd.function + "'," + cmd.argsToPython() + ")";
|
||||||
showMessage(command, LogInput);
|
showMessage(command, LogInput);
|
||||||
m_proc.write(command.toUtf8() + '\n');
|
m_proc.write(command + '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
void PdbEngine::shutdownInferior()
|
void PdbEngine::shutdownInferior()
|
||||||
|
@@ -1002,7 +1002,7 @@ bool DockerDevicePrivate::runInShell(const CommandLine &cmd) const
|
|||||||
QTC_ASSERT(m_shell, LOG("No shell. Could not run " << cmd.toUserOutput()); return false);
|
QTC_ASSERT(m_shell, LOG("No shell. Could not run " << cmd.toUserOutput()); return false);
|
||||||
QMutexLocker l(&m_shellMutex);
|
QMutexLocker l(&m_shellMutex);
|
||||||
m_shell->readAllStandardOutput(); // clean possible left-overs
|
m_shell->readAllStandardOutput(); // clean possible left-overs
|
||||||
m_shell->write(cmd.toUserOutput().toUtf8() + "\necho $?\n");
|
m_shell->write(cmd.toUserOutput() + "\necho $?\n");
|
||||||
QTC_ASSERT(m_shell->waitForReadyRead(), return false);
|
QTC_ASSERT(m_shell->waitForReadyRead(), return false);
|
||||||
QByteArray output = m_shell->readAllStandardOutput();
|
QByteArray output = m_shell->readAllStandardOutput();
|
||||||
bool ok;
|
bool ok;
|
||||||
@@ -1033,7 +1033,7 @@ QByteArray DockerDevicePrivate::outputForRunInShell(const CommandLine &cmd) cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
const QByteArray markerWithNewLine("___QC_DOCKER_" + randomHex() + "_OUTPUT_MARKER___\n");
|
const QByteArray markerWithNewLine("___QC_DOCKER_" + randomHex() + "_OUTPUT_MARKER___\n");
|
||||||
m_shell->write(cmd.toUserOutput().toUtf8() + "\necho -n \"" + markerWithNewLine + "\"\n");
|
m_shell->write(cmd.toUserOutput() + "\necho -n \"" + markerWithNewLine + "\"\n");
|
||||||
QByteArray output;
|
QByteArray output;
|
||||||
while (!output.endsWith(markerWithNewLine)) {
|
while (!output.endsWith(markerWithNewLine)) {
|
||||||
QTC_ASSERT(m_shell->isRunning(), return {});
|
QTC_ASSERT(m_shell->isRunning(), return {});
|
||||||
|
@@ -176,7 +176,6 @@ void MergeTool::chooseAction()
|
|||||||
}
|
}
|
||||||
|
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
QByteArray ba;
|
|
||||||
QVariant key;
|
QVariant key;
|
||||||
QAbstractButton *button = msgBox.clickedButton();
|
QAbstractButton *button = msgBox.clickedButton();
|
||||||
if (button)
|
if (button)
|
||||||
@@ -184,9 +183,8 @@ void MergeTool::chooseAction()
|
|||||||
// either the message box was closed without clicking anything, or abort was clicked
|
// either the message box was closed without clicking anything, or abort was clicked
|
||||||
if (!key.isValid())
|
if (!key.isValid())
|
||||||
key = QVariant('a'); // abort
|
key = QVariant('a'); // abort
|
||||||
ba.append(key.toChar().toLatin1());
|
|
||||||
ba.append('\n');
|
write(QString(key.toChar()) + '\n');
|
||||||
write(ba);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MergeTool::addButton(QMessageBox *msgBox, const QString &text, char key)
|
void MergeTool::addButton(QMessageBox *msgBox, const QString &text, char key)
|
||||||
@@ -268,10 +266,10 @@ void MergeTool::done()
|
|||||||
deleteLater();
|
deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MergeTool::write(const QByteArray &bytes)
|
void MergeTool::write(const QString &str)
|
||||||
{
|
{
|
||||||
m_process->write(bytes);
|
m_process->write(str);
|
||||||
VcsOutputWindow::append(QString::fromLocal8Bit(bytes));
|
VcsOutputWindow::append(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -71,7 +71,7 @@ private:
|
|||||||
void readData();
|
void readData();
|
||||||
void readLine(const QString &line);
|
void readLine(const QString &line);
|
||||||
void done();
|
void done();
|
||||||
void write(const QByteArray &bytes);
|
void write(const QString &str);
|
||||||
|
|
||||||
FileState parseStatus(const QString &line, QString &extraInfo);
|
FileState parseStatus(const QString &line, QString &extraInfo);
|
||||||
QString mergeTypeName();
|
QString mergeTypeName();
|
||||||
|
@@ -133,7 +133,7 @@ void StdIOClientInterface::sendData(const QByteArray &data)
|
|||||||
}
|
}
|
||||||
qCDebug(LOGLSPCLIENTV) << "StdIOClient send data:";
|
qCDebug(LOGLSPCLIENTV) << "StdIOClient send data:";
|
||||||
qCDebug(LOGLSPCLIENTV).noquote() << data;
|
qCDebug(LOGLSPCLIENTV).noquote() << data;
|
||||||
m_process.write(data);
|
m_process.writeRaw(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StdIOClientInterface::onProcessFinished()
|
void StdIOClientInterface::onProcessFinished()
|
||||||
|
@@ -326,7 +326,7 @@ void SshDeviceProcess::SshDeviceProcessPrivate::setState(SshDeviceProcess::SshDe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 SshDeviceProcess::write(const QByteArray &data)
|
qint64 SshDeviceProcess::write(const QString &data)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!usesTerminal(), return -1);
|
QTC_ASSERT(!usesTerminal(), return -1);
|
||||||
return d->remoteProcess->write(data);
|
return d->remoteProcess->write(data);
|
||||||
|
@@ -52,7 +52,7 @@ public:
|
|||||||
QByteArray readAllStandardOutput() override;
|
QByteArray readAllStandardOutput() override;
|
||||||
QByteArray readAllStandardError() override;
|
QByteArray readAllStandardError() override;
|
||||||
|
|
||||||
qint64 write(const QByteArray &data) override;
|
qint64 write(const QString &data) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void emitStarted() override;
|
void emitStarted() override;
|
||||||
|
@@ -233,8 +233,8 @@ void QbsSession::initialize()
|
|||||||
|
|
||||||
void QbsSession::sendQuitPacket()
|
void QbsSession::sendQuitPacket()
|
||||||
{
|
{
|
||||||
d->qbsProcess->write(Packet::createPacket(QJsonObject{qMakePair(QString("type"),
|
d->qbsProcess->writeRaw(Packet::createPacket(QJsonObject{qMakePair(QString("type"),
|
||||||
QJsonValue("quit"))}));
|
QJsonValue("quit"))}));
|
||||||
}
|
}
|
||||||
|
|
||||||
QbsSession::~QbsSession()
|
QbsSession::~QbsSession()
|
||||||
@@ -562,7 +562,7 @@ void QbsSession::sendRequestNow(const QJsonObject &request)
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(d->state == State::Active, return);
|
QTC_ASSERT(d->state == State::Active, return);
|
||||||
if (!request.isEmpty())
|
if (!request.isEmpty())
|
||||||
d->qbsProcess->write(Packet::createPacket(request));
|
d->qbsProcess->writeRaw(Packet::createPacket(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorInfo QbsSession::getErrorInfo(const QJsonObject &packet)
|
ErrorInfo QbsSession::getErrorInfo(const QJsonObject &packet)
|
||||||
|
@@ -872,10 +872,11 @@ public:
|
|||||||
QTC_CHECK(m_shell->readAllStandardOutput().isNull()); // clean possible left-overs
|
QTC_CHECK(m_shell->readAllStandardOutput().isNull()); // clean possible left-overs
|
||||||
QTC_CHECK(m_shell->readAllStandardError().isNull()); // clean possible left-overs
|
QTC_CHECK(m_shell->readAllStandardError().isNull()); // clean possible left-overs
|
||||||
|
|
||||||
const QByteArray prefix = !data.isEmpty()
|
QString prefix;
|
||||||
? QByteArray("echo '" + data.toBase64() + "' | base64 -d | ") : QByteArray("");
|
if (!data.isEmpty())
|
||||||
const QByteArray suffix = QByteArray(" > /dev/null 2>&1\necho $?\n");
|
prefix = "echo '" + QString::fromUtf8(data.toBase64()) + "' | base64 -d | ";
|
||||||
const QByteArray command = prefix + cmd.toUserOutput().toUtf8() + suffix;
|
const QString suffix = " > /dev/null 2>&1\necho $?\n";
|
||||||
|
const QString command = prefix + cmd.toUserOutput() + suffix;
|
||||||
|
|
||||||
m_shell->write(command);
|
m_shell->write(command);
|
||||||
DEBUG("RUN1 " << cmd.toUserOutput());
|
DEBUG("RUN1 " << cmd.toUserOutput());
|
||||||
@@ -896,8 +897,8 @@ public:
|
|||||||
QTC_CHECK(m_shell->readAllStandardError().isNull()); // clean possible left-overs
|
QTC_CHECK(m_shell->readAllStandardError().isNull()); // clean possible left-overs
|
||||||
auto cleanup = qScopeGuard([this] { m_shell->readAllStandardOutput(); }); // clean on assert
|
auto cleanup = qScopeGuard([this] { m_shell->readAllStandardOutput(); }); // clean on assert
|
||||||
|
|
||||||
const QByteArray suffix = QByteArray(" 2> /dev/null \necho $? 1>&2\n");
|
const QString suffix = " 2> /dev/null \necho $? 1>&2\n";
|
||||||
const QByteArray command = cmd.toUtf8() + suffix;
|
const QString command = cmd + suffix;
|
||||||
|
|
||||||
m_shell->write(command);
|
m_shell->write(command);
|
||||||
DEBUG("RUN2 " << cmd.toUserOutput());
|
DEBUG("RUN2 " << cmd.toUserOutput());
|
||||||
|
Reference in New Issue
Block a user