From 674e79416fefe7b5acf2a8c18d3c91d8feddcc18 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 7 Jul 2013 10:12:24 -0700 Subject: Fix incomplete override of QIODevice::open in QProcess and QLocalSocket The rule for a new override is that it must still work if the old implementation is called. The catch is that any class that derives from QProcess and isn't recompiled will still have QIODevice::open in its virtual table. That is equivalent to overriding open() and calling QIODevice::open() (like the tests). In Qt 5.0, QProcess::start() called QIODevice::open directly, not the virtual open(), so there's no expectation that a user-overridden open() be called. With that in mind, simply fix QProcess::start to not call the virtual open at all. Similarly with QLocalSocket, the calls to open were always non-virtual. Task-number: QTBUG-32284 Change-Id: I88925f0ba08bc23c849658b54582744997e69a4c Reviewed-by: Giuseppe D'Angelo --- src/corelib/io/qprocess.cpp | 59 ++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 22 deletions(-) (limited to 'src/corelib/io/qprocess.cpp') diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index b1861d8038..d8cd1f5fae 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1959,7 +1959,7 @@ void QProcess::start(const QString &program, const QStringList &arguments, OpenM d->program = program; d->arguments = arguments; - open(mode); + d->start(mode); } /*! @@ -1975,7 +1975,17 @@ void QProcess::start(const QString &program, const QStringList &arguments, OpenM */ void QProcess::start(OpenMode mode) { - open(mode); + Q_D(QProcess); + if (d->processState != NotRunning) { + qWarning("QProcess::start: Process is already running"); + return; + } + if (d->program.isEmpty()) { + qWarning("QProcess::start: program not set"); + return; + } + + d->start(mode); } /*! @@ -2008,34 +2018,39 @@ bool QProcess::open(OpenMode mode) return false; } + d->start(mode); + return true; +} + +void QProcessPrivate::start(QIODevice::OpenMode mode) +{ + Q_Q(QProcess); #if defined QPROCESS_DEBUG qDebug() << "QProcess::start(" << program << ',' << arguments << ',' << mode << ')'; #endif - d->outputReadBuffer.clear(); - d->errorReadBuffer.clear(); + outputReadBuffer.clear(); + errorReadBuffer.clear(); - if (d->stdinChannel.type != QProcessPrivate::Channel::Normal) - mode &= ~WriteOnly; // not open for writing - if (d->stdoutChannel.type != QProcessPrivate::Channel::Normal && - (d->stderrChannel.type != QProcessPrivate::Channel::Normal || - d->processChannelMode == MergedChannels)) - mode &= ~ReadOnly; // not open for reading + if (stdinChannel.type != QProcessPrivate::Channel::Normal) + mode &= ~QIODevice::WriteOnly; // not open for writing + if (stdoutChannel.type != QProcessPrivate::Channel::Normal && + (stderrChannel.type != QProcessPrivate::Channel::Normal || + processChannelMode == QProcess::MergedChannels)) + mode &= ~QIODevice::ReadOnly; // not open for reading if (mode == 0) - mode = Unbuffered; - QIODevice::open(mode); + mode = QIODevice::Unbuffered; + q->QIODevice::open(mode); - d->stdinChannel.closed = false; - d->stdoutChannel.closed = false; - d->stderrChannel.closed = false; + stdinChannel.closed = false; + stdoutChannel.closed = false; + stderrChannel.closed = false; - d->exitCode = 0; - d->exitStatus = NormalExit; - d->processError = QProcess::UnknownError; - d->errorString.clear(); - d->startProcess(); - - return true; + exitCode = 0; + exitStatus = QProcess::NormalExit; + processError = QProcess::UnknownError; + errorString.clear(); + startProcess(); } -- cgit v1.2.3