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

View File

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

View File

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

View File

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

View File

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