QProcessPrivate: merge the functions dealing with stdout and stderr

Simplifies the code.

Change-Id: I4b3a6e725eb245d3531d1d11d959fb3b85862778
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
This commit is contained in:
Thiago Macieira 2014-06-05 15:10:27 -07:00 committed by The Qt Project
parent 0f6b3a01e4
commit 25ef58fe18
5 changed files with 54 additions and 131 deletions

View File

@ -898,49 +898,51 @@ void QProcessPrivate::cleanup()
/*! /*!
\internal \internal
Returns true if we emitted readyRead().
*/ */
bool QProcessPrivate::_q_canReadStandardOutput() bool QProcessPrivate::tryReadFromChannel(Channel *channel)
{ {
Q_Q(QProcess); Q_Q(QProcess);
qint64 available = bytesAvailableFromStdout(); qint64 available = bytesAvailableInChannel(channel);
if (available == 0) { if (available == 0) {
if (stdoutChannel.notifier) if (channel->notifier)
stdoutChannel.notifier->setEnabled(false); channel->notifier->setEnabled(false);
closeChannel(&stdoutChannel); closeChannel(channel);
#if defined QPROCESS_DEBUG #if defined QPROCESS_DEBUG
qDebug("QProcessPrivate::canReadStandardOutput(), 0 bytes available"); qDebug("QProcessPrivate::tryReadFromChannel(%d), 0 bytes available", channel - &stdinChannel);
#endif #endif
return false; return false;
} }
char *ptr = stdoutChannel.buffer.reserve(available); char *ptr = channel->buffer.reserve(available);
qint64 readBytes = readFromStdout(ptr, available); qint64 readBytes = readFromChannel(channel, ptr, available);
if (readBytes == -1) { if (readBytes == -1) {
processError = QProcess::ReadError; processError = QProcess::ReadError;
q->setErrorString(QProcess::tr("Error reading from process")); q->setErrorString(QProcess::tr("Error reading from process"));
emit q->error(processError); emit q->error(processError);
#if defined QPROCESS_DEBUG #if defined QPROCESS_DEBUG
qDebug("QProcessPrivate::canReadStandardOutput(), failed to read from the process"); qDebug("QProcessPrivate::tryReadFromChannel(%d), failed to read from the process", channel - &stdinChannel);
#endif #endif
return false; return false;
} }
#if defined QPROCESS_DEBUG #if defined QPROCESS_DEBUG
qDebug("QProcessPrivate::canReadStandardOutput(), read %d bytes from the process' output", qDebug("QProcessPrivate::tryReadFromChannel(%d), read %d bytes from the process' output", channel - &stdinChannel
int(readBytes)); int(readBytes));
#endif #endif
if (stdoutChannel.closed) { if (channel->closed) {
stdoutChannel.buffer.chop(readBytes); channel->buffer.chop(readBytes);
return false; return false;
} }
stdoutChannel.buffer.chop(available - readBytes); channel->buffer.chop(available - readBytes);
bool didRead = false; bool didRead = false;
bool isStdout = channel == &stdoutChannel;
if (readBytes == 0) { if (readBytes == 0) {
if (stdoutChannel.notifier) if (channel->notifier)
stdoutChannel.notifier->setEnabled(false); channel->notifier->setEnabled(false);
} else if (processChannel == QProcess::StandardOutput) { } else if ((processChannel == QProcess::StandardOutput) == isStdout) {
didRead = true; didRead = true;
if (!emittedReadyRead) { if (!emittedReadyRead) {
emittedReadyRead = true; emittedReadyRead = true;
@ -948,53 +950,27 @@ bool QProcessPrivate::_q_canReadStandardOutput()
emittedReadyRead = false; emittedReadyRead = false;
} }
} }
if (isStdout)
emit q->readyReadStandardOutput(QProcess::QPrivateSignal()); emit q->readyReadStandardOutput(QProcess::QPrivateSignal());
else
emit q->readyReadStandardError(QProcess::QPrivateSignal());
return didRead; return didRead;
} }
/*!
\internal
*/
bool QProcessPrivate::_q_canReadStandardOutput()
{
return tryReadFromChannel(&stdoutChannel);
}
/*! /*!
\internal \internal
*/ */
bool QProcessPrivate::_q_canReadStandardError() bool QProcessPrivate::_q_canReadStandardError()
{ {
Q_Q(QProcess); return tryReadFromChannel(&stderrChannel);
qint64 available = bytesAvailableFromStderr();
if (available == 0) {
if (stderrChannel.notifier)
stderrChannel.notifier->setEnabled(false);
closeChannel(&stderrChannel);
return false;
}
char *ptr = stderrChannel.buffer.reserve(available);
qint64 readBytes = readFromStderr(ptr, available);
if (readBytes == -1) {
processError = QProcess::ReadError;
q->setErrorString(QProcess::tr("Error reading from process"));
emit q->error(processError);
return false;
}
if (stderrChannel.closed) {
stderrChannel.buffer.chop(readBytes);
return false;
}
stderrChannel.buffer.chop(available - readBytes);
bool didRead = false;
if (readBytes == 0) {
if (stderrChannel.notifier)
stderrChannel.notifier->setEnabled(false);
} else if (processChannel == QProcess::StandardError) {
didRead = true;
if (!emittedReadyRead) {
emittedReadyRead = true;
emit q->readyRead();
emittedReadyRead = false;
}
}
emit q->readyReadStandardError(QProcess::QPrivateSignal());
return didRead;
} }
/*! /*!

View File

@ -329,6 +329,7 @@ public:
bool openChannel(Channel &channel); bool openChannel(Channel &channel);
void closeChannel(Channel *channel); void closeChannel(Channel *channel);
void closeWriteChannel(); void closeWriteChannel();
bool tryReadFromChannel(Channel *channel); // obviously, only stdout and stderr
QString program; QString program;
QStringList arguments; QStringList arguments;
@ -386,10 +387,8 @@ public:
bool waitForFinished(int msecs = 30000); bool waitForFinished(int msecs = 30000);
bool waitForWrite(int msecs = 30000); bool waitForWrite(int msecs = 30000);
qint64 bytesAvailableFromStdout() const; qint64 bytesAvailableInChannel(const Channel *channel) const;
qint64 bytesAvailableFromStderr() const; qint64 readFromChannel(const Channel *channel, char *data, qint64 maxlen);
qint64 readFromStdout(char *data, qint64 maxlen);
qint64 readFromStderr(char *data, qint64 maxlen);
qint64 writeToStdin(const char *data, qint64 maxlen); qint64 writeToStdin(const char *data, qint64 maxlen);
void cleanup(); void cleanup();

View File

@ -963,45 +963,24 @@ bool QProcessPrivate::processStarted()
return i <= 0; return i <= 0;
} }
qint64 QProcessPrivate::bytesAvailableFromStdout() const qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const
{ {
int nbytes = 0; int nbytes = 0;
qint64 available = 0; qint64 available = 0;
if (::ioctl(stdoutChannel.pipe[0], FIONREAD, (char *) &nbytes) >= 0) if (::ioctl(channel->pipe[0], FIONREAD, (char *) &nbytes) >= 0)
available = (qint64) nbytes; available = (qint64) nbytes;
#if defined (QPROCESS_DEBUG) #if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::bytesAvailableFromStdout() == %lld", available); qDebug("QProcessPrivate::bytesAvailableInChannel(%d) == %lld", channel - &stdinChannel, available);
#endif #endif
return available; return available;
} }
qint64 QProcessPrivate::bytesAvailableFromStderr() const qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint64 maxlen)
{ {
int nbytes = 0; qint64 bytesRead = qt_safe_read(channel->pipe[0], data, maxlen);
qint64 available = 0;
if (::ioctl(stderrChannel.pipe[0], FIONREAD, (char *) &nbytes) >= 0)
available = (qint64) nbytes;
#if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::bytesAvailableFromStderr() == %lld", available);
#endif
return available;
}
qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen)
{
qint64 bytesRead = qt_safe_read(stdoutChannel.pipe[0], data, maxlen);
#if defined QPROCESS_DEBUG #if defined QPROCESS_DEBUG
qDebug("QProcessPrivate::readFromStdout(%p \"%s\", %lld) == %lld", qDebug("QProcessPrivate::readFromChannel(%d, %p \"%s\", %lld) == %lld",
data, qt_prettyDebug(data, bytesRead, 16).constData(), maxlen, bytesRead); channel - &stdinChannel,
#endif
return bytesRead;
}
qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen)
{
qint64 bytesRead = qt_safe_read(stderrChannel.pipe[0], data, maxlen);
#if defined QPROCESS_DEBUG
qDebug("QProcessPrivate::readFromStderr(%p \"%s\", %lld) == %lld",
data, qt_prettyDebug(data, bytesRead, 16).constData(), maxlen, bytesRead); data, qt_prettyDebug(data, bytesRead, 16).constData(), maxlen, bytesRead);
#endif #endif
return bytesRead; return bytesRead;

View File

@ -564,47 +564,26 @@ bool QProcessPrivate::processStarted()
return processState == QProcess::Running; return processState == QProcess::Running;
} }
qint64 QProcessPrivate::bytesAvailableFromStdout() const qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const
{ {
if (stdoutChannel.pipe[0] == INVALID_Q_PIPE) if (channel->pipe[0] == INVALID_Q_PIPE)
return 0; return 0;
if (!stdoutChannel.reader) if (!channel->reader)
return 0; return 0;
DWORD bytesAvail = stdoutChannel.reader->bytesAvailable(); DWORD bytesAvail = channel->reader->bytesAvailable();
#if defined QPROCESS_DEBUG #if defined QPROCESS_DEBUG
qDebug("QProcessPrivate::bytesAvailableFromStdout() == %d", bytesAvail); qDebug("QProcessPrivate::bytesAvailableInChannel(%d) == %d", channel - &stdinChannel, bytesAvail);
#endif #endif
return bytesAvail; return bytesAvail;
} }
qint64 QProcessPrivate::bytesAvailableFromStderr() const qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint64 maxlen)
{ {
if (stderrChannel.pipe[0] == INVALID_Q_PIPE) return channel->reader ? channel->reader->read(data, maxlen) : 0;
return 0;
if (!stderrChannel.reader)
return 0;
DWORD bytesAvail = stderrChannel.reader->bytesAvailable();
#if defined QPROCESS_DEBUG
qDebug("QProcessPrivate::bytesAvailableFromStderr() == %d", bytesAvail);
#endif
return bytesAvail;
} }
qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen)
{
return stdoutChannel.reader ? stdoutChannel.reader->read(data, maxlen) : 0;
}
qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen)
{
return stderrChannel.reader ? stderrChannel.reader->read(data, maxlen) : 0;
}
static BOOL QT_WIN_CALLBACK qt_terminateApp(HWND hwnd, LPARAM procId) static BOOL QT_WIN_CALLBACK qt_terminateApp(HWND hwnd, LPARAM procId)
{ {
DWORD currentProcId = 0; DWORD currentProcId = 0;
@ -740,14 +719,14 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
return true; return true;
// If we wouldn't write anything, check if we can read stdout. // If we wouldn't write anything, check if we can read stdout.
if (bytesAvailableFromStdout() != 0) { if (bytesAvailableInChannel(&stdoutChannel) != 0) {
_q_canReadStandardOutput(); tryReadFromChannel(&stdoutChannel);
timer.resetIncrements(); timer.resetIncrements();
} }
// Check if we can read stderr. // Check if we can read stderr.
if (bytesAvailableFromStderr() != 0) { if (bytesAvailableInChannel(&stderrChannel) != 0) {
_q_canReadStandardError(); tryReadFromChannel(&stderrChannel);
timer.resetIncrements(); timer.resetIncrements();
} }

View File

@ -174,22 +174,12 @@ bool QProcessPrivate::processStarted()
return processState == QProcess::Running; return processState == QProcess::Running;
} }
qint64 QProcessPrivate::bytesAvailableFromStdout() const qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *) const
{ {
return 0; return 0;
} }
qint64 QProcessPrivate::bytesAvailableFromStderr() const qint64 QProcessPrivate::readFromChannel(const Channel *, char *data, qint64 maxlen)
{
return 0;
}
qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen)
{
return -1;
}
qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen)
{ {
return -1; return -1;
} }