Core: Consolidate QProcess error reporting

Introduce two methods to set set error and errorString, and optionally
emit the error() signal. This also fixes two places where errorString
hasn't been set previously.

Change-Id: Ib7c27ff2daff898745e8e20ff8f11eaae568697f
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
This commit is contained in:
Kai Koehne 2015-06-17 17:01:43 +02:00
parent 5c0ff27d9b
commit 5147f73ac3
5 changed files with 78 additions and 79 deletions

View File

@ -895,6 +895,48 @@ void QProcessPrivate::cleanup()
#endif
}
/*!
\internal
*/
void QProcessPrivate::setError(QProcess::ProcessError error, const QString &description)
{
processError = error;
if (description.isEmpty()) {
switch (error) {
case QProcess::FailedToStart:
errorString = QProcess::tr("Process failed to start");
case QProcess::Crashed:
errorString = QProcess::tr("Process crashed");
break;
case QProcess::Timedout:
errorString = QProcess::tr("Process operation timed out");
break;
case QProcess::ReadError:
errorString = QProcess::tr("Error reading from process");
break;
case QProcess::WriteError:
errorString = QProcess::tr("Error writing to process");
break;
case QProcess::UnknownError:
errorString.clear();
break;
}
} else {
errorString = description;
}
}
/*!
\internal
*/
void QProcessPrivate::setErrorAndEmit(QProcess::ProcessError error, const QString &description)
{
Q_Q(QProcess);
Q_ASSERT(error != QProcess::UnknownError);
setError(error, description);
emit q->error(processError);
}
/*!
\internal
Returns true if we emitted readyRead().
@ -918,9 +960,7 @@ bool QProcessPrivate::tryReadFromChannel(Channel *channel)
return false;
}
if (readBytes == -1) {
processError = QProcess::ReadError;
q->setErrorString(QProcess::tr("Error reading from process"));
emit q->error(processError);
setErrorAndEmit(QProcess::ReadError);
#if defined QPROCESS_DEBUG
qDebug("QProcessPrivate::tryReadFromChannel(%d), failed to read from the process", channel - &stdinChannel);
#endif
@ -1004,9 +1044,7 @@ bool QProcessPrivate::_q_canWrite()
stdinChannel.buffer.nextDataBlockSize());
if (written < 0) {
closeChannel(&stdinChannel);
processError = QProcess::WriteError;
q->setErrorString(QProcess::tr("Error writing to process"));
emit q->error(processError);
setErrorAndEmit(QProcess::WriteError);
return false;
}
@ -1075,9 +1113,7 @@ bool QProcessPrivate::_q_processDied()
if (crashed) {
exitStatus = QProcess::CrashExit;
processError = QProcess::Crashed;
q->setErrorString(QProcess::tr("Process crashed"));
emit q->error(processError);
setErrorAndEmit(QProcess::Crashed);
} else {
#ifdef QPROCESS_USE_SPAWN
// if we're using posix_spawn, waitForStarted always succeeds.
@ -1085,8 +1121,8 @@ bool QProcessPrivate::_q_processDied()
// 127 if anything prevents the target program from starting.
// http://pubs.opengroup.org/onlinepubs/009695399/functions/posix_spawn.html
if (exitStatus == QProcess::NormalExit && exitCode == 127) {
processError = QProcess::FailedToStart;
q->setErrorString(QProcess::tr("Process failed to start (spawned process exited with code 127)"));
setError(QProcess::FailedToStart,
QProcess::tr("Process failed to start (spawned process exited with code 127)"));
}
#endif
}
@ -1130,8 +1166,7 @@ bool QProcessPrivate::_q_startupNotification()
}
q->setProcessState(QProcess::NotRunning);
processError = QProcess::FailedToStart;
emit q->error(processError);
setErrorAndEmit(QProcess::FailedToStart);
#ifdef Q_OS_UNIX
// make sure the process manager removes this entry
waitForDeadChild();
@ -1939,9 +1974,7 @@ qint64 QProcess::writeData(const char *data, qint64 len)
#if defined(Q_OS_WINCE)
Q_UNUSED(data);
Q_UNUSED(len);
d->processError = QProcess::WriteError;
setErrorString(tr("Error writing to process"));
emit error(d->processError);
d->setErrorAndEmit(QProcess::WriteError);
return -1;
#endif
@ -2220,9 +2253,7 @@ void QProcess::start(const QString &command, OpenMode mode)
QStringList args = parseCombinedArgString(command);
if (args.isEmpty()) {
Q_D(QProcess);
d->processError = QProcess::FailedToStart;
setErrorString(tr("No program defined"));
emit error(d->processError);
d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined"));
return;
}

View File

@ -383,6 +383,8 @@ public:
qint64 writeToStdin(const char *data, qint64 maxlen);
void cleanup();
void setError(QProcess::ProcessError error, const QString &description = QString());
void setErrorAndEmit(QProcess::ProcessError error, const QString &description = QString());
#ifdef Q_OS_BLACKBERRY
QList<QSocketNotifier *> defaultNotifiers() const;

View File

@ -203,8 +203,8 @@ bool QProcessPrivate::openChannel(Channel &channel)
channel.pipe[1] = -1;
if ( (channel.pipe[0] = qt_safe_open(fname, O_RDONLY)) != -1)
return true; // success
q->setErrorString(QProcess::tr("Could not open input redirection for reading"));
setErrorAndEmit(QProcess::FailedToStart,
QProcess::tr("Could not open input redirection for reading"));
} else {
int mode = O_WRONLY | O_CREAT;
if (channel.append)
@ -216,12 +216,9 @@ bool QProcessPrivate::openChannel(Channel &channel)
if ( (channel.pipe[1] = qt_safe_open(fname, mode, 0666)) != -1)
return true; // success
q->setErrorString(QProcess::tr("Could not open output redirection for writing"));
setErrorAndEmit(QProcess::FailedToStart,
QProcess::tr("Could not open input redirection for reading"));
}
// could not open file
processError = QProcess::FailedToStart;
emit q->error(processError);
cleanup();
return false;
} else {
@ -330,9 +327,7 @@ void QProcessPrivate::startProcess()
!openChannel(stdoutChannel) ||
!openChannel(stderrChannel) ||
qt_create_pipe(childStartedPipe) != 0) {
processError = QProcess::FailedToStart;
q->setErrorString(qt_error_string(errno));
emit q->error(processError);
setErrorAndEmit(QProcess::FailedToStart, qt_error_string(errno));
cleanup();
return;
}
@ -458,9 +453,8 @@ void QProcessPrivate::startProcess()
qDebug("fork failed: %s", qPrintable(qt_error_string(lastForkErrno)));
#endif
q->setProcessState(QProcess::NotRunning);
processError = QProcess::FailedToStart;
q->setErrorString(QProcess::tr("Resource error (fork failure): %1").arg(qt_error_string(lastForkErrno)));
emit q->error(processError);
setErrorAndEmit(QProcess::FailedToStart,
QProcess::tr("Resource error (fork failure): %1").arg(qt_error_string(lastForkErrno)));
cleanup();
return;
}
@ -808,8 +802,6 @@ void QProcessPrivate::killProcess()
bool QProcessPrivate::waitForStarted(int msecs)
{
Q_Q(QProcess);
#if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::waitForStarted(%d) waiting for child to start (fd = %d)", msecs,
childStartedPipe[0]);
@ -819,8 +811,7 @@ bool QProcessPrivate::waitForStarted(int msecs)
FD_ZERO(&fds);
FD_SET(childStartedPipe[0], &fds);
if (qt_select_msecs(childStartedPipe[0] + 1, &fds, 0, msecs) == 0) {
processError = QProcess::Timedout;
q->setErrorString(QProcess::tr("Process operation timed out"));
setError(QProcess::Timedout);
#if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::waitForStarted(%d) == false (timed out)", msecs);
#endif
@ -847,7 +838,6 @@ QList<QSocketNotifier *> QProcessPrivate::defaultNotifiers() const
bool QProcessPrivate::waitForReadyRead(int msecs)
{
Q_Q(QProcess);
#if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::waitForReadyRead(%d)", msecs);
#endif
@ -890,8 +880,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
break;
}
if (ret == 0) {
processError = QProcess::Timedout;
q->setErrorString(QProcess::tr("Process operation timed out"));
setError(QProcess::Timedout);
return false;
}
@ -927,7 +916,6 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
bool QProcessPrivate::waitForBytesWritten(int msecs)
{
Q_Q(QProcess);
#if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::waitForBytesWritten(%d)", msecs);
#endif
@ -972,8 +960,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
}
if (ret == 0) {
processError = QProcess::Timedout;
q->setErrorString(QProcess::tr("Process operation timed out"));
setError(QProcess::Timedout);
return false;
}
@ -1002,7 +989,6 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
bool QProcessPrivate::waitForFinished(int msecs)
{
Q_Q(QProcess);
#if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::waitForFinished(%d)", msecs);
#endif
@ -1046,8 +1032,7 @@ bool QProcessPrivate::waitForFinished(int msecs)
break;
}
if (ret == 0) {
processError = QProcess::Timedout;
q->setErrorString(QProcess::tr("Process operation timed out"));
setError(QProcess::Timedout);
return false;
}

View File

@ -217,7 +217,8 @@ bool QProcessPrivate::openChannel(Channel &channel)
if (channel.pipe[0] != INVALID_Q_PIPE)
return true;
q->setErrorString(QProcess::tr("Could not open input redirection for reading"));
setErrorAndEmit(QProcess::FailedToStart,
QProcess::tr("Could not open input redirection for reading"));
} else {
// open in write mode
channel.pipe[0] = INVALID_Q_PIPE;
@ -237,12 +238,9 @@ bool QProcessPrivate::openChannel(Channel &channel)
return true;
}
q->setErrorString(QProcess::tr("Could not open output redirection for writing"));
setErrorAndEmit(QProcess::FailedToStart,
QProcess::tr("Could not open output redirection for writing"));
}
// could not open file
processError = QProcess::FailedToStart;
emit q->error(processError);
cleanup();
return false;
} else {
@ -504,9 +502,10 @@ void QProcessPrivate::startProcess()
environment.isEmpty() ? 0 : envlist.data(),
workingDirectory.isEmpty() ? 0 : (wchar_t*)QDir::toNativeSeparators(workingDirectory).utf16(),
&startupInfo, pid);
QString errorString;
if (!success) {
// Capture the error string before we do CloseHandle below
q->setErrorString(QProcess::tr("Process failed to start: %1").arg(qt_error_string()));
errorString = QProcess::tr("Process failed to start: %1").arg(qt_error_string());
}
if (stdinChannel.pipe[0] != INVALID_Q_PIPE) {
@ -524,8 +523,7 @@ void QProcessPrivate::startProcess()
if (!success) {
cleanup();
processError = QProcess::FailedToStart;
emit q->error(processError);
setErrorAndEmit(QProcess::FailedToStart, errorString);
q->setProcessState(QProcess::NotRunning);
return;
}
@ -595,16 +593,13 @@ void QProcessPrivate::killProcess()
bool QProcessPrivate::waitForStarted(int)
{
Q_Q(QProcess);
if (processStarted())
return true;
if (processError == QProcess::FailedToStart)
return false;
processError = QProcess::Timedout;
q->setErrorString(QProcess::tr("Process operation timed out"));
setError(QProcess::Timedout);
return false;
}
@ -636,8 +631,6 @@ bool QProcessPrivate::drainOutputPipes()
bool QProcessPrivate::waitForReadyRead(int msecs)
{
Q_Q(QProcess);
QIncrementalSleepTimer timer(msecs);
forever {
@ -663,15 +656,12 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
break;
}
processError = QProcess::Timedout;
q->setErrorString(QProcess::tr("Process operation timed out"));
setError(QProcess::Timedout);
return false;
}
bool QProcessPrivate::waitForBytesWritten(int msecs)
{
Q_Q(QProcess);
QIncrementalSleepTimer timer(msecs);
forever {
@ -731,14 +721,12 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
break;
}
processError = QProcess::Timedout;
q->setErrorString(QProcess::tr("Process operation timed out"));
setError(QProcess::Timedout);
return false;
}
bool QProcessPrivate::waitForFinished(int msecs)
{
Q_Q(QProcess);
#if defined QPROCESS_DEBUG
qDebug("QProcessPrivate::waitForFinished(%d)", msecs);
#endif
@ -770,8 +758,7 @@ bool QProcessPrivate::waitForFinished(int msecs)
break;
}
processError = QProcess::Timedout;
q->setErrorString(QProcess::tr("Process operation timed out"));
setError(QProcess::Timedout);
return false;
}
@ -814,13 +801,10 @@ qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen)
bool QProcessPrivate::waitForWrite(int msecs)
{
Q_Q(QProcess);
if (!stdinChannel.writer || stdinChannel.writer->waitForWrite(msecs))
return true;
processError = QProcess::Timedout;
q->setErrorString(QProcess::tr("Process operation timed out"));
setError(QProcess::Timedout);
return false;
}

View File

@ -138,8 +138,7 @@ void QProcessPrivate::startProcess()
if (!success) {
cleanup();
processError = QProcess::FailedToStart;
emit q->error(processError);
setErrorAndEmit(QProcess::FailedToStart);
q->setProcessState(QProcess::NotRunning);
return;
}
@ -210,8 +209,7 @@ bool QProcessPrivate::waitForStarted(int)
if (processError == QProcess::FailedToStart)
return false;
processError = QProcess::Timedout;
q->setErrorString(QProcess::tr("Process operation timed out"));
setError(QProcess::Timedout);
return false;
}
@ -251,8 +249,7 @@ bool QProcessPrivate::waitForFinished(int msecs)
if (timer.hasTimedOut())
break;
}
processError = QProcess::Timedout;
q->setErrorString(QProcess::tr("Process operation timed out"));
setError(QProcess::Timedout);
return false;
}