summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qprocess_unix.cpp
diff options
context:
space:
mode:
authorAlex Trotsenko <alex1973tr@gmail.com>2016-04-08 16:55:39 +0300
committerAlex Trotsenko <alex1973tr@gmail.com>2016-04-30 13:13:26 +0000
commita4d26cf522b966056e47e47a004b7e4d668e3a2d (patch)
tree7e26cda8249fd557f411a030a05dfa2cb7ca4af5 /src/corelib/io/qprocess_unix.cpp
parentc9f9f54d3f79915723270b2a6d06216a54c87433 (diff)
QWindowsPipeWriter: ensure validity of the write buffer
QWindowsPipeWriter uses asynchronous API to perform writing. Once a cycle has been started, the write buffer must remain valid until the write operation is completed. To avoid data corruption and possibly undefined behavior, this patch makes QWindowsPipeWriter::write() take a QByteArray, which it keeps alive for the duration of the write cycle. Autotest-by: Thomas Hartmann Task-number: QTBUG-52401 Change-Id: Ia35faee735c4e684267daa1f6bd689512b670cd2 Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
Diffstat (limited to 'src/corelib/io/qprocess_unix.cpp')
-rw-r--r--src/corelib/io/qprocess_unix.cpp35
1 files changed, 25 insertions, 10 deletions
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index df13a2533e..fda91780d0 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -620,21 +620,36 @@ qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint
return bytesRead;
}
-qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen)
+bool QProcessPrivate::writeToStdin()
{
- qint64 written = qt_safe_write_nosignal(stdinChannel.pipe[1], data, maxlen);
+ const char *data = stdinChannel.buffer.readPointer();
+ const qint64 bytesToWrite = stdinChannel.buffer.nextDataBlockSize();
+
+ qint64 written = qt_safe_write_nosignal(stdinChannel.pipe[1], data, bytesToWrite);
#if defined QPROCESS_DEBUG
- qDebug("QProcessPrivate::writeToStdin(%p \"%s\", %lld) == %lld",
- data, qt_prettyDebug(data, maxlen, 16).constData(), maxlen, written);
+ qDebug("QProcessPrivate::writeToStdin(), write(%p \"%s\", %lld) == %lld",
+ data, qt_prettyDebug(data, bytesToWrite, 16).constData(), bytesToWrite, written);
if (written == -1)
qDebug("QProcessPrivate::writeToStdin(), failed to write (%s)", qPrintable(qt_error_string(errno)));
#endif
- // If the O_NONBLOCK flag is set and If some data can be written without blocking
- // the process, write() will transfer what it can and return the number of bytes written.
- // Otherwise, it will return -1 and set errno to EAGAIN
- if (written == -1 && errno == EAGAIN)
- written = 0;
- return written;
+ if (written == -1) {
+ // If the O_NONBLOCK flag is set and If some data can be written without blocking
+ // the process, write() will transfer what it can and return the number of bytes written.
+ // Otherwise, it will return -1 and set errno to EAGAIN
+ if (errno == EAGAIN)
+ return true;
+
+ closeChannel(&stdinChannel);
+ setErrorAndEmit(QProcess::WriteError);
+ return false;
+ }
+ stdinChannel.buffer.free(written);
+ if (!emittedBytesWritten && written != 0) {
+ emittedBytesWritten = true;
+ emit q_func()->bytesWritten(written);
+ emittedBytesWritten = false;
+ }
+ return true;
}
void QProcessPrivate::terminateProcess()