aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Burchell <robin.burchell@crimson.no>2017-05-25 13:21:37 +0200
committerRobin Burchell <robin.burchell@crimson.no>2017-05-25 16:41:20 +0000
commitfbb1baf3e197d0882cee3f69e5f16ef33e6a9af0 (patch)
tree0fdc6dc24b6e24893056bc4c26908e3e9d9f5de3
parent0f68ffdd206487bec3bf675e673a0b817a9a3951 (diff)
Fix partial reads of stdout/stderr
This had only a cosmetic effect of printing subprocess output with extra linebreaks, but since it's not hard to fix, let's do that. Change-Id: I5a81be5c29df84a5632fe2599ac31f35ae7e2f0f Reviewed-by: Gunnar Sletta <gunnar@crimson.no>
-rw-r--r--src/main.cpp46
1 files changed, 32 insertions, 14 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 685c5a1..d83ffb0 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -288,28 +288,46 @@ int runHostProcess(const QCoreApplication &app, const QStringList &positionalArg
sanitizedArgCopy.append(b.fileName);
QProcess *p = new QProcess;
+ QByteArray stdErrBuf;
QObject::connect(p, &QProcess::readyReadStandardError, p, [&]() {
- QStringList lines = QString::fromLatin1(p->readAllStandardError()).split("\n");
- for (const QString &ln : lines) {
- if (!ln.isEmpty())
- std::cerr << "SUB: " << ln.toLocal8Bit().constData() << "\n";
+ stdErrBuf += p->readAllStandardError();
+ int nlIdx = 0;
+ forever {
+ nlIdx = stdErrBuf.indexOf('\n');
+ if (nlIdx == -1)
+ break;
+ QByteArray ln = stdErrBuf.left(nlIdx);
+ stdErrBuf = stdErrBuf.right(stdErrBuf.size() - nlIdx - 1);
+ std::cerr << "SUB: " << ln.constData() << "\n";
}
});
- QByteArray jsonOutput;
+ QByteArray stdOutBuf;
QObject::connect(p, &QProcess::readyReadStandardOutput, p, [&]() {
- QStringList lines = QString::fromLatin1(p->readAllStandardOutput()).split("\n");
- for (const QString &ln : lines) {
- if (!Options::instance.printJsonToStdout) {
- if (!ln.isEmpty())
- std::cout << "SUB: " << ln.toLocal8Bit().constData() << "\n";
- } else {
- jsonOutput += ln.toUtf8();
- }
+ stdOutBuf += QString::fromLocal8Bit(p->readAllStandardOutput());
+ if (Options::instance.printJsonToStdout)
+ return;
+ int nlIdx = 0;
+ forever {
+ nlIdx = stdOutBuf.indexOf('\n');
+ if (nlIdx == -1)
+ break;
+ QByteArray ln = stdOutBuf.left(nlIdx);
+ stdOutBuf = stdOutBuf.right(stdOutBuf.size() - nlIdx - 1);
+ std::cout << "SUB: " << ln.constData() << "\n";
}
});
+ QObject::connect(p,
+ static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
+ [=](int /*exitCode*/, QProcess::ExitStatus /*exitStatus*/) {
+ // Flush the leftovers (if any)
+ std::cerr << "SUB: " << stdErrBuf.constData() << "\n";
+ if (!Options::instance.printJsonToStdout)
+ std::cout << "SUB: " << stdOutBuf.constData() << "\n";
+ });
+
if (ret == 0) {
p->start(app.arguments().first(), sanitizedArgCopy);
if (!p->waitForFinished(60*10*1000)) {
@@ -334,7 +352,7 @@ int runHostProcess(const QCoreApplication &app, const QStringList &positionalArg
// Turn stdout into a JSON object and merge our results into the
// final ones.
QJsonParseError jerr;
- QJsonDocument d = QJsonDocument::fromJson(jsonOutput, &jerr);
+ QJsonDocument d = QJsonDocument::fromJson(stdOutBuf, &jerr);
if (d.isNull()) {
qWarning() << "Can't parse JSON for result for " << b.fileName;
qWarning() << "Error: " << jerr.errorString();